Understanding switchMap
The switchMap operator merges the behavior of two distinct operators: map and switchAll. Through the map component, you can transform an emission from a higher-order source observable into an inner observable. The switch component then operates much like switchAll – it subscribes to the newest inner observable produced by the outer stream and cancels the subscription to any former inner observable.
At any given moment, switchMap maintains a single active subscription, and only emissions from that subscription are forwarded to the observer. Whenever the outer observable emits, switchMap invokes the provided function to generate a fresh inner stream and immediately switches over to it. This process involves unsubscribing from the existing inner subscription and re-subscribing to the newly created one.
Here is a step-by-step breakdown of its operation:
- Establish a subscription to the outer (higher-order) observable.
- Upon each emission from the outer source, call the mapping function to produce an inner observable.
- Subscribe to that newly created inner observable.
- Forward any emissions from the inner observable down to the observer.
- When the outer source emits again, invoke the mapping function once more to obtain another inner observable.
- Terminate the existing inner subscription and subscribe to the new inner observable.
- The complete notification is sent to the observer only when the outer source and all inner observables have completed.
- Should any inner observable throw an error, the error notification is passed along to the observer.
It’s important to note that switchAll will remain uncompleted if any of the input streams fail to finish.
When to Use It
There are situations where consuming emissions from every inner sequence is undesirable. Often, you only require the values originating from the most recent inner stream. A classic illustration of this is a type-ahead search feature. Imagine a user typing into a search field, causing a request to be dispatched to a server. Since this operation is asynchronous, its response arrives as an observable. If the user modifies the text in the search box before the response comes back, another request is fired. Consequently, two searches have now been initiated. However, the results from the first search are no longer relevant. If those outdated results were interleaved with the latest ones, the user would be left with a confusing and incorrect display. This is precisely where switchAll becomes valuable. It ensures that only emissions from the latest inner sequence are processed, effectively discarding any prior streams.
Consider this example to see switchMap in action as it toggles between two streams:
const urls = [
'https://api.mocki.io/v1/0350b5d5',
'https://api.mocki.io/v1/ce5f60e2'
];
from(urls).pipe(
switchMap((url) => {
return fromFetch(url);
})
).subscribe((response) => console.log(response.status));
