Reputation: 4925
Here is a simple flow of what I want to achieve:
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
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