Reputation: 5970
Is it possible to avoid nested subscribe in the following code?
this.requestService().subscribe(
() => this.success(),
error => {
const errorDescription = {
one: 5,
two: 10
};
return this.error(errorDescription).subscribe();
}
);
The second subscribe
is part of the error callback of the Observer. How could we use e.g. switchMap
as to have only one subscribe?
Upvotes: 1
Views: 479
Reputation: 5364
Seems like you need a catchError
, that will let you substitute an error with another stream. Though we'll have to update successful result handling:
this.requestService().pipe(
// handle success value
tap(() => this.success()),
// when an error happens
catchError(error => {
const errorDescription = {
one: 5,
two: 10
};
// we switch to `this.error` stream
return this.error(errorDescription);
})
).subscribe(value=>{
// ...here you'll receive both:
// events from the requestService()
// and events from this.error(errorDescription)
});
Heres an article with detailed overview of error handling in RxJS
Hope this helps
Upvotes: 1
Reputation: 29355
I would probably do it like this:
this.requestService().pipe(catchError(e => {
const errorDescription = {
one: 5,
two: 10
};
return this.error(errorDescription).pipe(switchMap(empty()));
// the switch to empty will prevent the error going to success
// consider moving this into the error handler itself.
})).subscribe(
() => this.success(),
error => {
//should never get here.
}
);
the catchError -> switchMap -> empty is a pattern that appears pretty frequently in my code as my error handlers should stop the processing chain more often than not.
Upvotes: 0
Reputation: 2091
Here's an idea to avoid a 'nested' subscribe. With the code you provided, this is the best I can come up with. If you have any questions, let me know and I'll help.
import { of, throwError } from 'rxjs';
import { map, switchMap, catchError } from 'rxjs/operators';
// this.requestService().subscribe(
// () => this.success(),
// error => {
// const errorDescription = {
// one: 5,
// two: 10
// };
// return this.error(errorDescription).subscribe();
// }
// );
const error = throwError('oops');
const success = of('success!');
const handleError = (d) => of({one: 5, two: 10}).pipe(
map(n => n),
catchError(e => 'could not do 2nd network request')
);
const requestServiceSuccess = success.pipe(
switchMap(d => of(d)),
catchError(handleError)
)
const requestServiceFail = error.pipe(
switchMap(d => of(d)),
catchError(handleError)
)
// if your first network request succeeds, then you will see success
requestServiceSuccess.subscribe(
(d) => console.log(d),
(e) => console.log(e)
)
// if your first network request fails, then you will see your errorDescription
requestServiceFail.subscribe(
(d) => console.log(d),
(e) => console.log(e)
)
You can paste this into stackblitz to check the logs
https://stackblitz.com/fork/rxjs?devtoolsheight=60
Upvotes: 0