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:
- getting an entity from the API (for example: a profile, article or group). See Getting an entity from the API
- getting a list of entities from the API (for example: a list of posts) See Getting a collection from the API
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
getStateparameter if you do not use it