Reputation: 669
My use case is to map an Observable to redux actions of success and failure. I make a network call (with a function that gives promise), if it succeeds I have to forward a success action, if it fails than an error action. The Observable itself shall keep going. For all I could search, RxJS do not have a mechanism for this catching the error and retrying the original. I have following solution in my code which I am not happy with:
error$ = new Rx.Subject();
searchResultAction$ = search$
.flatMap(getSearchResultsPromise)
.map((resuls) => {
return {
type: 'SUCCESS_ACTION',
payload: {
results
}
}
})
.retryWhen((err$) => {
return err$
.pluck('query')
.do(error$.onNext.bind(error$));
});
searchErrorAction$
.map((query) => {
return {
type: 'ERROR_ACTION',
payload: {
query,
message: 'Error while retrieving data'
}
}
});
action$ = Observable
.merge(
searchResultAction$,
searchErrorAction$
)
.doOnError(err => console.error('Ignored error: ', err))
.retry();
action$.subscribe(dispatch);
i.e I create a subject, and push errors into that subject and create an Observable of error actions from that.
Is there a better alternative of doing this in RxJS that I am missing? Basically I want to emit a notification of what error has occurred, and then continue with whatever the Observable is already doing.
Upvotes: 9
Views: 4567
Reputation: 39182
This would retry failed queries:
var action$ = search$
.flatMap(value => {
// create an observable that will execute
// the query each time it is subscribed
const query = Rx.Observable.defer(() => getSearchResultsPromise(value));
// add a retry operation to this query
return query.retryWhen(errors$ => errors$.do(err => {
console.log("ignoring error: ", err);
}));
})
.map(payload => ({ type: "SUCCESS_ACTION", payload }));
action$.subscribe(dispatcher);
If you don't want to retry, but just want to notify or ignore errors:
var action$ = search$
.flatMap(value => {
// create an observable that will execute
// the query each time it is subscribed
const query = Rx.Observable.defer(() => getSearchResultsPromise(value));
// add a catch clause to "ignore" the error
return query.catch(err => {
console.log("ignoring error: ", err);
return Observable.empty(); // no result for this query
}));
})
.map(payload => ({ type: "SUCCESS_ACTION", payload }));
action$.subscribe(dispatcher);
Upvotes: 11