Shivam Sahil
Shivam Sahil

Reputation: 4925

How to dispatch multiple actions in react redux?

Here is a simple flow of what I want to achieve:

enter image description here

And here is the components executions:

onClick function:

this.props.FetchQueryData({dateRange: this.props.dateData.dateRange, selections: selections});

Redux FetchQueryData function:

export const fetchSidebBatData = (sideBarData) => {
    return dispatch => {
        dispatch(fetchSidebBatDataBegin()); //For turning on isLoading
        console.log("Started");
        //For fetching the data
        Object.keys(data).forEach(element => { //Here Data is an object to get the right endpoint
            axios.post(`${ApiEndPoints.getDropDownHeadersByAdvertiserId}${element}`, sideBarData)
           .then(response => {
               data[element] = response.data;
               //Once the action is completed turning off isLoading
               dispatch(fetchSidebBatDataEnd());
           })
           .catch(e => {
               console.log(e);
               //If there's an error turning off isLoading
               dispatch(fetchSidebBatDataEnd());
            });
       },console.log(data));
       console.log("Ended");
    };

};

Here is my reducer:

const reducer = ( state = initState, action ) => {
    switch ( action.type ) {

        case actionTypes.FETCH_SIDEBAR_DATA: return fetchSideBarData(state, action);
        case actionTypes.FETCH_SIDEBAR_DATA_START: return fetchSideBarDataBegin(state);
        case actionTypes.FETCH_SIDEBAR_DATA_END: return fetchSideBarDataEnd(state);
        default: return state;
    }
};

and here is my fetchSideBarDataBegin and fetchSideBarDataEnd functions:

const fetchSideBarDataBegin = (state) => {

    const newState = state;
    newState.isFetching = true;
    return newState;
};

const fetchSideBarDataEnd = (state) => {

    const newState = state;
    newState.isFetching = false;
    return newState;
};

I know I am missing something critical as I am not at all dispatching the data but I am totally new to redux and don't have a good context of how do you dispatch multiple actions within a reducer. Your help is highly appreciated. If you feel this is kind of complex example you can pick your own and just demonstrate the flow as I have shared in image which would be extremely helpful for me in understanding what to do next.

Note my major problem is that I want to set isLoading to true before fetching the data and that change should reflect in component and once the process is over then I want to turn it back to false.

Thanks in Advance

Upvotes: 1

Views: 3120

Answers (1)

Aadil Mehraj
Aadil Mehraj

Reputation: 2614

You can update the reducer with the terminology that is quite common in redux:

const initState = {
   data: [],
   error: false,
   isLoading: false
};

const reducer = ( state = initState, action ) => {
    switch ( action.type ) {

        case actionTypes.FETCH_SIDEBAR_DATA_REQUEST: {
            return {
              ...state,
              data: [], // reset data if previous
              error: false, // clear previous error if any
              isLoading: true,
            }
         };
        case actionTypes.FETCH_SIDEBAR_DATA_SUCCESS: {
            return {
              ...state,
              data: action.data,
              isLoading: false,
            }
         };
        case actionTypes.FETCH_SIDEBAR_DATA_ERROR:  {
            return {
              ...state,
              error: true,
              isLoading: false,
            }
         };
        default: return state;
    }
};

Notice to have three different action types: FETCH_SIDEBAR_DATA_REQUEST, FETCH_SIDEBAR_DATA_SUCCESS, and FETCH_SIDEBAR_DATA_ERROR

Edit: It seems you are doing multiple request in the thunk, you can handle that as:

export const fetchSidebBatData = (sideBarData) => {
    return dispatch => {
       dispatch(fetchSidebBatDataRequest());

       const requests = Object.keys(data).map(element => {
            return axios.post(`${ApiEndPoints.getDropDownHeadersByAdvertiserId}${element}`, sideBarData)
               .then(response => {
                   return { [element]: response.data };
               });
       };
       
       Promise.all(requests).then(data => {
          dispatch(fetchSidebBatDataSuccess(data));
       }).catch(error) {
          dispatch(fetchSidebBatDataError(error));
       }
    };

};

Upvotes: 3

Related Questions