I have the following code in my service
let b = new BehaviorSubject({ a: undefined })
let o = b.asObservable();
o.pipe(filter(_ => _.a === 5)).subscribe(() => {
debugger;
}, error => {
debugger
})
b.next({ a: 10 })
b.next({ a: 5 })
b.error({ a: 10 })
When I invoke b.next({a:10}) it does not hit the debugger in the onNext callback When I invoke b.next({a:5}) it hits the debugger in the onNext callback. When I invoke b.error({a:10}) it hits the debugger in the onError callback.
My expectation was the onError callback should not be called since the filter condition was not satisfied. But, clearly I have something wrong here.
How do I filter the errors too?
Thank you in advance.
You can't filter error
s for the same reason you can't filter complete
s. It doesn't make sense. They signal the end of a stream. You can't filter the end.
You can, of course, catch an error and then do nothing - which feels a bit like filtering an error.
o.pipe(
catchError(err =>
err?.a === 5 ?
return of(err) :
EMPTY
),
filter(val => val.a === 5)
).subscribe({
next: val => debugger,
error: err => debugger,
complete: () => debugger
});
Of course, anything you send to the subject after you error or complete will do nothing.
b.next({ a: 10 }); // Filtered, not emitted
b.next({ a: 5 }); // value emitted
b.error({ a: 5 }); // caught and new non-error { a: 5 } emitted as value. subject 'b' is done
b.next({ a: 5 }); // Does nothing
That final call will do nothing as the subject has errored/completed.
Similarily:
b.next({ a: 10 }); // Filtered, not emitted
b.next({ a: 5 }); // value emitted
b.complete(); // subject 'b' is done
b.next({ a: 5 }); // Does nothing
Finally:
b.next({ a: 10 }); // Filtered, not emitted
b.next({ a: 5 }); // value emitted
b.error({ a: 10 }); // caught and not emitted. subject 'b' is done
b.next({ a: 5 }); // Does nothing