Noel
Noel

Reputation: 83

Wait on action within an action in redux

I am trying to reuse one of my action. My actions look like this:

const actions = {
changeStage: (data: Object) => (dispatch) => {
        return new Promise((resolve) => {
            dispatch({type: ACTION_TYPES.Loader, payload: "Loading"});
            resolve();
        })
        .then(() => {
            return serviceCallToChangeStage(data); 
        })
        .catch((str: string) => {
            dispatch({type:ACTION_TYPES.error, payload: str});
        });
    }

I want to reuse the above action in another action which is shown below:

changeStageAndSaveData: (data: Object) => (dispatch) => {
        return new Promise((resolve) => {
            dispatch({type: ACTION_TYPES.Loader, payload: "Loading"});
            resolve();
        })
        .then(() => { //This is where I want to re-use
            if(certainCondition){
                return actions.changeStage(data);
            }
        }
        .then(() => {
            return saveDataThroughServiceCall(data); 
        })
        .catch((str: string) => {
            dispatch({type:ACTION_TYPES.error, payload: str});
        });
    }

For some reason, if I do return actions.changeStage(data), it is not executing. If I do a dispatch on that actions.changeStage(), the second servicecall gets executed right away without waiting for the previous call to return. Since both my actions are already wrapped in promises, I would expect it to be re-usable with a return. What am I missing?

Upvotes: 0

Views: 94

Answers (1)

HMR
HMR

Reputation: 39260

You can do the following:

const actions = {
  changeStage: (data: Object) => (dispatch) => {
    //dispatch is not async no need for the promise yet
    dispatch({
      type: ACTION_TYPES.Loader,
      payload: 'Loading',
    });
    //I assume serviceCallToChangeStage returns a promise
    return serviceCallToChangeStage(data).catch(
      (str: string) => {
        dispatch({
          type: ACTION_TYPES.error,
          payload: str,
        });
      }
    );
  },
  changeStageAndSaveData: (data: Object) => (dispatch) => {
    //no need to create a promise yet
    dispatch({
      type: ACTION_TYPES.Loader,
      payload: 'Loading',
    });
    //here you can return a promise
    return Promise.resolve(
      certainCondition &&
        actions.changeStage(data)(dispatch)
    )
      .then(() => saveDataThroughServiceCall(data))
      .catch((str: string) => {
        dispatch({
          type: ACTION_TYPES.error,
          payload: str,
        });
      });
  },
};

Upvotes: 1

Related Questions