0

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);
                });
    });
};
torvin
  • 6,515
  • 1
  • 37
  • 52
dace
  • 5,819
  • 13
  • 44
  • 74

1 Answers1

1

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);
            });
    });
};
torvin
  • 6,515
  • 1
  • 37
  • 52
  • Thanks @torvin - this makes sense and got my code working. Appreciate the help! – dace Nov 27 '17 at 21:24
  • 1
    @hidace I cannot recommend [this article](https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html) about Promise-releated mistakes more. Your mistake is even listed as mistake #1 in it :) – torvin Nov 27 '17 at 23:08