0

I want to add an item using a POST request, then close the pop-up window and update the item list with a GET request. Using redux-thunk, I could call the 2 latter actions after the getting result from POST.

Now I want to call loadAll action to populate the updated list of item and finish the state change/rendering before calling toggleAddItem, which actually close the pop-up window.

export const loadAllItems = items => ({
    type: LOAD_ALL_ITEMS,
    payload: items
});

export const toggleAddItem = status => ({
    type: TOGGLE_ADD_ITEM,
    payload: status
})

export const loadAll = () => (dispatch => {
    axios.get('/getAllItems').then(res => {
        dispatch(loadAllItems(res.data))
    })
    .catch(err => {
        console.log(err);
    })
});

export const addItemAndRefresh = input => ((dispatch, getState) => {
axios.post('/addItem', input)
  .then(() => {
      axios.get('/getAllItems')
      .then(res => {
          dispatch(loadAll(res.data))
      })
      .then(() => {
          dispatch(toggleAddItem(false));
      })
  })
  .catch(err => {
      console.log(err);
  })
});

With the above code, I manage to call the loadAll before toggleAddItem. However, with componentDidUpdate log, I realize that toggleAddItem actually fires when loadAll is still updating state/rendering and even finish before the former action.

So far, this is my best attempt, however, I'm not sure if this sequence can avoid all issues. There are previous cases when pop-up window is closed, and state is updated with new items. However, new item list is not rendered (I suspect that this happens because I update the state while the rendering function is working, so it skips the second render).

What would be the best implementation for dispatching consequential actions and make sure that both will be rendered?

1 Answer 1

1

You need to call then on the promise returned from the loadAll action.

Firstly return that promise by changing your loadAll to:

export const loadAll = () => dispatch => {
    return axios.get('/getAllItems')
      .then(res => {
          dispatch(loadAllItems(res.data))
      })
      .catch(err => {
          console.log(err);
      })
};

Then in your mapDispatchToProps call then and then pass a function which will be called when loadAll resolves.

const mapDispatchToProps = dispatch => ({
  addItemAndRefresh: dispatch(loadAll())
                      .then(() => dispatch(toggleAddItem(false)))
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.