Basic API requests

For basic API requests, we use helper Redux actions in the apiRequest module. We usually don't dispatch these actions directly. Instead, we create wrapper actions for each endpoint.

When not to use the apiRequest module:

API Documentation

For more details on the helper actions, see the API documentation here

Example: POST request

The following action creator performs a POST request to the /post endpoint. Before adding such an action creator, search the codebase to make sure it doesn't already exist.

export const CREATE_COMMUNITY_POST = 'communityActions/CREATE_COMMUNITY_POST';

/**
 * Creates a new post in the community
 * @param title {string} The title of the post
 * @param text {string} The text content of the post
 * @param tags {Array<number>} An array of tag ids to attach to the post
 * @param images {Array<string>} An array of base64 encoded image strings
 */
export const createCommunityPost = (title, text, tags, images) => apiPost(
  CREATE_COMMUNITY_POST,
  GATEWAY_COMMUNITY_AUTH,
  '/posts',
  {
    title,
    text,
    tags,
    media: imageInputRESTFormatter(images),
  },
);

A couple of things to note in the above example:

  • First, create a constant string that represents the action type for the resulting redux action. This action type is passed to the first argument of apiPost() can be seen in Redux devtools when the request starts and finishes.
  • As a convention we usually give the same name to the action type as the action creator. The action type is typed in UPPER_CASE and the action creator in camelCase.
  • It is a good practice to document the action creator parameters using JSDoc annotations.

Example: handling the API response

Sometimes it is needed to perform some other action after the API response comes back. This can be done with the Promise returned when dispatching the action:

const myAction = (dispatch, getState) => { // create a thunk action
  dispatch(apiPost(  // dispatch the api action
    MY_ACTION,
    GATEWAY_CONTENT_AUTH,
    '/someEndpoint'
  )).then((result) => { // chain on the Promise returned by dispatch()

    // this code executes once the API responded successfully

  });
};

An example of this can be seen in the updateUserTimeZone action. Here we first do a PATCH call and afterwards dispatch a setEntity action.

export const UPDATE_TIMEZONE = 'accountActions/UPDATE_TIMEZONE';

export const updateUserTimeZone = timeZone => (dispatch, getState) => {
  const memberId = userIdSelector(getState());
  return dispatch(apiPatch(
    UPDATE_TIMEZONE,
    GATEWAY_ACCOUNT_AUTH,
    `/accounts/${memberId}/`,
    {
      timeZoneId: timeZone,
    }
  )).then(result => dispatch(setEntity(ACCOUNT, memberId, result, true)));
};

Notes:

  • If you are unfamiliar with Redux thunks (the action = () => (dispatch, getState) => { notation), have a look at the redux-thunk docs
  • You may omit the getState parameter if you do not use it