taking the following code as example:
const subject$ = new Subject();
subject$
.pipe(
tap(() => console.log('tap1')),
switchMap(() => EMPTY),
tap(() => console.log('tap2')),
finalize(() => console.log('finalize')),
).subscribe();
subject$.next(null);
What i'm trying to achieve is the following output:
Expected Output:
tap1
finalize
Actual Output:
tap1
Reading what each operator does it should work as expected but it doesn't.
My thought process was:
tap2 to not be logged and finalize to be logged since the chained observable has been completed.I am clearly not getting it right. Could anyone help me understand the flow and how to make it work for my need please?
switchMap() emits complete notification only when both its merged Observable completes and its source Observable completes.
Since at the top of your chain you have a Subject that emits complete only when you call complete() function, switchMap() will never complete.
More detailed example: A very common use-case for switchMap() is merging an async HTTP request in for example typeahead search field like this:
fromEvent(this.input.nativeElement, 'keyup')
.pipe(
map(event => event.target.value),
debounceTime(500),
switchMap(search => API call goes here),
)
.subscribe(res => {
console.log(res)
});
If switchMap() emitted complete notification when its inner Observable completed (that's when the API call ended) then this chain would search only once. However, fromEvent() never completes and that's why when you continue typing it's going to make subsequent API calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With