I have a Subject (this.searchSubject) which I call next() on when I want to perform a search:
this.searchSubject.next(postBody)
This causes the following to fire:
this.searchSubject
.switchMap((view: any) => {
// upsert here records the search - needed
return this.searchHistoryService.upsert(view)
.flatMap(() => this.http.post(this.url, view))
.map((data) => this.pageTransform(data));
})
.subscribe(res => {
this.successSubject.next(this.pageTransform(res));
}, err => {
this.errorSub.next(err);
});
Unfortunately, no matter what I do, I can't seem to keep the stream alive if this.errorSub.next(err);
is called (the error condition).
Since the httpClient (this.http.post) returns a new observable each I wouldnt have thought handling the error would be an issue, but it seems this removes all observers from this.searchSubject.
Note I have a httpInterceptor which returns a thrown error for every error returned.
This must be an extremely common pattern, so what am I doing wrong?
Your error handler is in the outer switchMap projection, thus it will close the outer stream in case of an error. You'll have to move it inside to your switchMap
to keep the outer stream alive.
And since you're using rxjs@5.5.2
you can use the lettable operators which might make it easier to see where to put your error handlers.
this.searchSubject.pipe(
switchMap((view: any) => {
return this.searchHistoryService.upsert(view)
.pipe(
flatMap(() => this.http.post(this.url, view)),
map((data) => this.pageTransform(data)),
catchError(() => {
this.errorSub.next(err);
})
);
})
).subscribe(() => {
this.successSubject.next(this.pageTransform(res));
});
An important note if you switch to the lettable operators is that you have to import them from rxjs/operators
like import { map, catchError } from 'rxjs/operators';
.
If you stay with the old syntax I think it will be as easy as to add a .catch
after your .map()
projection.