I have an rxjs BehaviorSubject
I subscribe to using an async
pipe from Angular 2 and I have a catch
to handle eventual errors it throws.
P
It is a generally bad idea to manually dispatch an error on a Subject, that is supposed to only eject data (like the BehaviorSubject
in your case). The reason is, that when an error occurs on a Subject
, the Subject
is essentially dead -> meaning, that no new data can be ejected on it any more. This is one of the core-concepts of rxjs. Here is a small example:
let stream$ = new Rx.BehaviorSubject(1);
stream$.subscribe(x => console.log("Logging: " + x), e => console.error("Error: " + e)); // logs 1, 2, Error: ...
stream$.next(2);
stream$.error(new Error("Some error message."));
stream$.next(3); // this will have no effect, because the stream is "dead"
stream$.subscribe(x => console.log("Logging 2: " + x), e => console.error("Error: " + e)); // this will just log the error
For your case this means that you did some error-handling, but then just return the "old, dead, error"-Subject - in other words: propagate the error down the stream. (I'm not assuming that handleError()
creates a fresh Subject
, which would be an awful practice anyways.)
In general it means that .error
should only be used for streams that perform a defined operation and have a defined number of results and then complete or throw an error, but not on Subject
s that you want to emit data throughout the complete lifetime of the application.
How to solve this in your case: The quick&dirty (really dirty!!) way would be to use two separate Subjects, one for the data and one for errors (eject with .next
).
The proper fix: Split up your architecture into a data-generation-flow and into a data-store-part.
The lifecycle would look something like this:
Generative Flow
Subscribing Flow
The perfect fix would be to use a ready-to-use thought-through store-architecture like ngrx, however implementing this in an existing project will come with major refactoring requirements.