Reputation: 10571
I am pretty new to reactive programming, and would like to translate the following piece of code from redux-saga
to redux-observable
.
The idea is to wait for some API call, wait 5s and dispatch another action.
function* mySaga(action) {
const response = yield call(someApiCall);
yield call(delay, 5000);
yield put({ type: 'ACTION' });
}
Here's how I would have done it in redux-observable:
action$
.ofType('SOME_ACTION')
.mergeMap(someApiCall)
.delay(5000)
.map(() => ({ type: 'ACTION' }))
Upvotes: 2
Views: 606
Reputation: 15401
Your translation is accurate, assuming you omitted the yield takeEvery('SOME_ACTION', mySaga)
stuff in your original example.
I would however recommend isolating your Observable chain; put all the stuff to apply after someApiCall()
, inside the mergeMap
:
action$
.ofType('SOME_ACTION')
.mergeMap(action =>
someApiCall()
.delay(5000)
.map(() => ({ type: 'ACTION' }))
)
Even though it makes no functional difference in your example, if you or a team member later comes in and tries to add error handling it critical you don't let the error bubble outside the mergeMap
:
action$
.ofType('SOME_ACTION')
.mergeMap(action =>
someApiCall()
.delay(5000)
.map(() => ({ type: 'ACTION' }))
.catch(error => Observable.of({
type: 'SOME_ACTION_FAILED',
payload: error
}))
)
If you had placed the catch
on the top-level Observable, after the mergeMap
, the error would bubble to the top-level chain and although you would catch the error, your epic would no longer be listening for future actions.
If it isn't clear why, I recommend learning more about how Observables + operators work--I promise isn't not that scary! Here's a great video that even touches on "isolating your observable chains" to catch errors at the correct point. https://youtu.be/3LKMwkuK0ZE?t=20m15s
Upvotes: 3