0

How to call an async action after another action was successfully dispatched?

I am learning Redux and I have some questions, about async action.(I am using thunk)
I have two action:

export const addToCart = addToCartData => dispatch => {
  axios.post("/api/cart/add-to-cart", {addToCartData)
    .then(res => {
      dispatch({ type: ADD_TO_CART, payload: res.data });
    })
    .catch(err => console.log(err));
};

export const removeProduct = (userID) => dispatch => {
  axios
    .delete(`/api/wait-list/remove/${userID}`)
    .then(res => {
      dispatch({ type: REMOVE_FROM_WAITLIST, payload: res.data });
    })
    .catch(err => console.log(err));
};

And I want to execute removeProduct action only after addToCart will be successfully executed! I am trying to do third one with two of them, it looks like this:

export const addToCartAndPemoveProduct = (data) => dispatch => {
  dispatch(addToCart(data)
  dispatch(removeProduct(data));

But it executes removeProduct action first, and after addToCart....
How do I can do it right due to order? Maybe I should return a promise from first one and execute second one after it will be successfull resolve? It will be looking like this:

export const addToCart = addToCartData => dispatch => {
  return axios.post("/some", {addToCartData)
    .then(res => { dispatch({ type: ADD.....})
};


export const addToCartAndPemoveProduct = (data) => dispatch => {
  dispatch(addToCart({ userID, productId }))
  .then(data => {
     dispatch(removeProduct({ userID, productName, productDescr }));
  })
}

Is it ok or not?

Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
jsDev
  • 136
  • 2
  • 12
  • definitely, returning promises to chain async actions is a pretty common use case for redux-thunk – Hunter McMillen Apr 06 '18 at 16:06
  • @HunterMcMillen thank you for response,till this moment I was not sure about returning the promise, but now absolutely sure. – jsDev Apr 06 '18 at 16:26
  • Noob here. It is possible to chain promises as suggested but I wonder can't we check if addToCart is successful and if it is go on, if not dispatch a failure action within an async function? Is this a bad logic? – devserkan Apr 06 '18 at 16:43
  • @devserkan Maybe this helps: https://medium.com/collaborne-engineering/returning-promises-from-redux-action-creators-3035f34fa74b or this one https://stackoverflow.com/questions/35069212/return-promise-from-store-after-redux-thunk-dispatch?rq=1 – jsDev Apr 06 '18 at 20:05
  • Thanks for the links. What I'm thinking for this situation is something like this: https://pastebin.com/Gu8FbQD1 – devserkan Apr 06 '18 at 20:47
  • Take a look at [redux-saga](https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html). It helps you write side-effects to your store in a much more maintainable way then just chaining together promises. – Shobhit Chittora Apr 08 '18 at 08:27

1 Answers1

0

Do you always want to dispatch removeProduct after addToCart? In this case:

export const addToCart = addToCartData => dispatch => {
    // You'll have to get the userId here first, probably from getState() if it's not being passed in.

  axios.post("/api/cart/add-to-cart", {addToCartData)
      .then(res => {
          dispatch({ type: ADD_TO_CART, payload: res.data });
          dispatch(removeProduct(userId));
      })
      .catch(err => console.log(err));
};

Maybe rename the action to moveProductFromWaitListToCart to express the full transaction.

timotgl
  • 2,865
  • 1
  • 9
  • 19
  • Thank you for response, I **don't** want to always dispatch `removeProduct` after `addToCart`. – jsDev Apr 06 '18 at 16:44