How to make multiple API requests in a Promise in a Redux action

1.6k Views Asked by At

I'm working with React/Redux in a project and I need to make 2 separate API requests, but the second request depends on the first returning without any issues. In the below example of an action, I'm trying to wrap both calls in a promise, but it's not quite working (getting a Uncaught Error: Actions must be plain objects. Use custom middleware for async actions. error in the console). I don't necessarily need to do anything with the response data as a result of both calls. I just need them to return a 200 status or an error.

Note: Unfortunately, I can't use async/await for this example. Thanks!

export default () => {
    const url = '/api';
    const options = {...}
    const otherOptions = {...}

    return new Promise((resolve, reject) => {
        return dispatch =>
            // First API request
            axios.post(url, options)
                .then(responseA => dispatch({ type: RESPONSE_A_SUCCESS }))
                .then(() =>
                    // Second separate API request

                    axios.post(url, otherOptions)
                        .then(responseB => { 
                            dispatch({ type: RESPONSE_B_SUCCESS });
                            resolve();
                         })
                )
                .catch(error => {
                    dispatch({ type: errorActionType, error: error });
                    reject(error);
                });
    });
};
1

There are 1 best solutions below

2
On BEST ANSWER

Your code has 2 issues:

  1. It returns a promise, which is not a "plain object".
  2. You are nesting promises instead of attaching them sequentally

Try this instead:

export default () => {
    const url = '/api';
    const options = {...}
    const otherOptions = {...}

    return dispatch =>
        axios.post(url, options)
            .then(responseA => dispatch({ type: RESPONSE_A_SUCCESS }))
            .then(() => axios.post(url, otherOptions))
            .then(responseB => dispatch({ type: RESPONSE_B_SUCCESS }))
            .catch(error => {
                dispatch({ type: errorActionType, error: error });
                reject(error);
            });
    });
};