I have couple of observables combined in one observable with combineLatest. Also I have one inner switchMap
observable that in real example makes an http request to remote server.
Now I wonder, how can the combined observable continue working in case if switchMap
returns error ?
I've created simplified example here
//emit every 2.5 seconds
const first = interval(2500);
//emit every 2 seconds
const second = interval(2000);
//emit every 1.5 seconds
const third = interval(1500);
//emit every 1 second
const fourth = interval(1000);
let count = 0;
//emit outputs from one observable
const example = combineLatest(
first.pipe(mapTo("FIRST!")),
second.pipe(mapTo("SECOND!")),
third.pipe(mapTo("THIRD")),
fourth.pipe(mapTo("FOURTH"))
)
.pipe(
switchMap(data => {
console.log(data);
count++;
// here lets asume in some cases http request getting error
return count < 5 ? of("switchMap") : throwError("This is an error!");
}),
catchError(err => of(err))
)
.subscribe(val => console.log(val));
Output
["FIRST!", "SECOND!", "THIRD", "FOURTH"]
switchMap
["FIRST!", "SECOND!", "THIRD", "FOURTH"]
switchMap
["FIRST!", "SECOND!", "THIRD", "FOURTH"]
switchMap
["FIRST!", "SECOND!", "THIRD", "FOURTH"]
switchMap
["FIRST!", "SECOND!", "THIRD", "FOURTH"]
This is an error!
So after getting error combineLatest
observable's work stops. In my real example I have 4 filters, and after changing filters I make http request.
The stream itself from the combineLatest
will end when an error occurs.
You can prevent it by adding the catchError
to the Observable returned in your switchMap
.
That way, the main stream is not altered and will continue to live.
const first = interval(2500);
const second = interval(2000);
const third = interval(1500);
const fourth = interval(1000);
let count = 0;
combineLatest(
first.pipe(mapTo("FIRST!")),
second.pipe(mapTo("SECOND!")),
third.pipe(mapTo("THIRD")),
fourth.pipe(mapTo("FOURTH"))
).pipe(
switchMap(data => {
count++;
const obs$ = count < 5
? of("switchMap")
: throwError("This is an error!");
return obs$.pipe(
catchError(err => of(err))
);
})
).subscribe(val => console.log(val));