Search code examples
reduxreact-reduxredux-saga

Redux Saga - Why does yield all not wait for the put action to complete before proceeding


I want to wait for all the put actions within my yieldall to complete before moving on to the next yield. I thought that that was what yieldall is supposed to achieve. I am new to Redux Saga hence there might be some details or logic that I am missing out on.

Here is my workerAnalytics (the first worker called using dispatch 'ANALYTICS')

export function* workerAnalytics(action) {
    console.log('here')
    let group = action.group
    yield put({ type: 'SHOW_LOADER', loading: action.loading })
    yield all([
        put({ type: 'BASIC_ANALYTICS', loading: 'client', group: group }),
        put({ type: 'BASIC_ANALYTICS', loading: 'KPI', group: group }),
        put({ type: 'BASIC_ANALYTICS', loading: 'country', group: group }),
        put({ type: 'BASIC_ANALYTICS', loading: 'estimated_revenue' }),
    ])
    console.log('there')
    yield put({ type: 'HIDE_LOADER', loading: action.loading })
}

my workerBasicAnalytics (called after watcherBasicAnalytics is called from dispatch type 'BASIC_ANALYTICS')

export function* workerBasicAnalytics(action) {
    try {
        let data;
        if (action.loading === 'KPI') { yield put({ type: 'SHOW_LOADER', loading: action.loading }) }
        data = action.loading === 'client' ? yield call(() => axiosInstance.get(`/customer-conversion/?group=${action.group}`)) :
            action.loading === 'KPI' ? yield call(() => axiosInstance.get(`/kpi/?group=${action.group}`)) :
                action.loading === 'country' ? yield call(() => axiosInstance.get(`/customer-country/?group=${action.group}`)) :
                    action.loading === 'estimated_revenue' ? yield call(() => axiosInstance.get('/estimated-revenue/')) : null
        yield put({ type: "STORE_DATA", payload: data.data, fetch: action.loading })
        if (action.loading === 'KPI') { yield put({ type: 'HIDE_LOADER', loading: action.loading }) }
        console.log(action.loading)

    } catch (error) {
        console.log(error)
    }
}

As you can see, I have console.log throughout my worker functions to keep track of which is executed first. The issue is that 'there' is logged right after 'here', when it should have been the individual workerBasicAnalytics console.log(action.loading) that should have been logged before the 'there' is logged, as the console.log('there') comes after the yieldall.

All help is appreciated, thanks all!


Solution

  • Did you check if workerBasicAnalytics is even called? Or if you caught the error in catch handler?

    Update: You can do this:

    yield all([
      workerBasicAnalytics({loading: 'client', group: group}), 
      workerBasicAnalytics({loading: 'KPI', group: group}
    )]