0
votes

I am using redux-thunk to make action calls and reducers to return back states. My actions are essentially axios API requests to the back end. For one particular action, I need a set events dispatched in the exact order as they are shown in the code:

  1. Check if tokenvalue passed by the user is valid (which has its own axios api request to the tokencollection). If 1. fails, jump to the catch block.
  2. If token is indeed valid, register the user using axios post. if 2. fails, jump to catch block
  3. If user was registered successfully, set the token to the user (thus only one unique token per user). If 3. fails, jump to catch block.

In order to implement them sequentially in the order above, I put them in try-catch blocks. Turns out my understanding of how dispatch works is wrong - if a dispatch fails with an error, it still executes subsequent dispatches. Any suggestions on how I can solve this? :

export const register = ({name,email,password,tokenval}) => async(dispatch) =>{
try{
    await dispatch(checkTokenValidity(tokenval)); // if this fails, jump to catch block
    const res = await axios.post("/api/users", body, config); //if this fails jump to catch
    await dispatch(setUserToToken({ tokenval, userID: res.data.userID })); //if this fails jump to catch
    dispatch({
      type: REGISTER_SUCCESS,
      payload: res.data,
    });
}catch(err){
  dispatch({
      type: REGISTER_FAIL,
    });
}
};
1

1 Answers

0
votes
  • make sure that the checkTokenValidity throws an error upon fail. With this, it automatically goes to catch block
  • no need to use dispatch and await for token validity
  • store api results in variables and make required checks and dispatch the actions accordingly.

Your refactored code

export const register = ({ name, email, password, tokenval }) => async (
  dispatch
) => {
  try {
    const isValidToken = await checkTokenValidity(tokenval); // no need of dispatch - just make sure that the checkTokenValidity throws an error upon fail
    if(!isValidToken ){
        throw new Error('server error - invalid token')
    }
    const usersResult = await axios.post("/api/users", body, config); //if this fails jump to catch
    if(!usersResult ){
        throw new Error('server error - usersResult')
    }
    const setUserToTokenResults = await dispatch(setUserToToken({ tokenval, userID: res.data.userID })); //if this fails jump to catch
    if(!setUserToTokenResults ){
        throw new Error('server error - setUserToTokenResults')
    }
    dispatch({
      type: REGISTER_SUCCESS,
      payload: res.data,
    });
  } catch (err) {
    dispatch({
      type: REGISTER_FAIL,
      payload: {err} //<---- provide some error message to the reducer
    });
  }
};