I'm cancelling a saga action when CANCEL_SEARCH is called:
function* cancelWorkerSaga(task) {
console.log(task);
yield cancel(task);
}
export default function* sagaFlights() {
const workerTask = yield takeLatest(GET_FLIGHTS, getFlights);
yield takeLatest(CANCEL_SEARCH, cancelWorkerSaga, workerTask);
}
The cancel action is working fine but when i navigate to home screen and tried to make a new search the getFlights actions is not being called anymore. What am i doing wrong?
The task returned from takeLatest is a watcher task that listens for the action GET_FLIGHTS to be disptached, not the currently running getFlights saga. Since the watcher is parent to the getFlights saga, canceling it will cancel getFlights as well.
To avoid canceling the watcher, you can either replace takeLatest with a custom loop so you have access to the fork task of getFlights or you can put one more saga in between to handle the cancellation:
export default function* sagaFlights() {
yield takeLatest(GET_FLIGHTS, function*(...args) {
yield race([
call(getFlights, ...args),
take(CANCEL_SEARCH)
]);
});
}
If you are going to need this pattern often, you can create a simple utility function to hide the logic:
const cancelable = (saga, cancelAction) => function*(...args) {
yield race([call(saga, ...args), take(cancelAction)]);
};
function* rootSaga() {
yield takeLatest(GET_A, cancelable(getA, CANCEL_A));
yield takeLatest(GET_B, cancelable(getB, CANCEL_B));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With