Search code examples
javascriptreactjsredux-saga

How can I run the code even when API fails


I have an action that calls a saga (where I make an API call). The action is being called twice in a loop.

index.js



componentDidMount(){
        this.props.nameList.map((name) => { 
             this.props.actions.getDetails(this.props.store.requestBody[name], name);
        })
    }

action.js

export const getDetails= (data, name) => ({
    type: GET_DETAILS,
    ...{data, name}
})

saga.js

export function* getDetails({data, name}){
    try{
        const response = yield call(getDetailsApi, data);
        if (response) {
            yield put(setDetails({[name] : response.data}));
        }
    }
    catch(error){
        yield put(setDetails({[name] : ''}));
    }
}


export default function* rootSaga() {
    yield takeLatest(GET_DETAILS, getDetails);
}

What I am trying here is that if try is, if successful, update reducer with response and if it fails, update reducer with ' ' (code in catch block).

The problem is if both the API calls fail, which they do sometimes, the catch() is called only once (for the first API call fail).

How can I update my reducer every time an API fail occurs?


Solution

  • Looks like the issue was due to the helper fn takeLatest(). Changing it to takeEvery() worked for me.

    Unlike takeEvery, takeLatest allows only one fetchData task to run at any moment. And it will be the latest started task. If a previous task is still running when another fetchData task is started, the previous task will be automatically cancelled.