Reputation: 7008
Moving a large codebase built on redux-thunk over to redux-observable and am struggling to figure out the semantics of an epic that will:
Here's what I've got so far:
export function editEpic(action$, unusedStore, { xhrClient }) {
return action$
.ofType(LOAD_ACTION)
.map(({ apiParams, operationId }) => {
// xhrClient is an object with methods on it that
// return a Promise of the data
const editOperation = xhrClient[operationId];
// call the api now
return editOperation(apiParams);
})
.map(result => {
return { type: SUCCESS_ACTION, result };
})
.catch(error => {
// We never get here..
return { type: FAILURE_ACTION, error };
});
}
This works just fine when the API call is successful, however in the event that the Promise rejects with an error, the catch
operation never gets called.
Could someone point me in the right direction here? We are using:
Upvotes: 1
Views: 163
Reputation: 85132
I believe the issue is that that first .map should instead be a .switchMap, .concatMap, or .mergeMap instead. To verify this, stick a log statement in the success case to see what result
equals, and i expect you'll see that it's a promise, not the value that the promise resolves to. Furthermore, the promise will be in a pending state; not yet resolved/rejected.
The choice of switch vs concat vs merge will depend on what you want to do if multiple LOAD_ACTION are kicked off in quick succession before the first one can complete. Switch will cancel the first in favor of the new one; concat will wait for the first to complete before moving on to the second; merge will do them in whatever order it can, with no guarantee of the order of the results.
Upvotes: 1