Understanding switchAll
switchAll is designed to work with a source observable that emits other observable instances. This type of source is known as a higher-order observable, and the observables it emits are termed inner observables. The core behavior of this operator is to track the latest inner observable emitted by the higher-order source, maintaining an active subscription only to that one. If a new inner observable arrives, the operator immediately unsubscribes from the previous one.
At any given moment, switchAll manages a single active subscription, and only values from that subscription are forwarded to the downstream observer. When the higher-order observable produces a fresh inner stream, the operator performs a switch: it tears down the existing subscription and establishes a new one with the incoming observable.
Values streamed from the currently active inner observable are relayed directly into the output sequence. In RxJS documentation, this process of merging inner streams into a single output is typically described as flattening.
The operational sequence of switchAll unfolds as follows:
- It subscribes to the higher-order source observable.
- When the higher-order source emits an inner observable, it subscribes to that inner observable.
- As values are produced by the inner observable, they are passed down to the observer.
- If a new inner observable is emitted from the higher-order source, the operator unsubscribes from the current inner observable.
- It then subscribes to the newly emitted inner observable.
- The complete notification is sent to the observer only when the higher-order source and all inner observables have completed.
- If any of the inner observables or the source throws an error, the error notification is delivered to the observer.
It is important to note that switchAll will not emit a complete notification if any of the involved streams fail to reach completion.
Consider the diagram below: the higher-order stream H emits two inner streams, A and B. Initially, the operator subscribes to A and forwards its values downstream. However, the moment B is released from the source, switchAll unsubscribes from A, subscribes to B, and continues the flow with values from B only.

Practical Application
There are scenarios where receiving values from every inner sequence is unnecessary or even problematic. In certain cases, only the data from the most recently emitted inner observable is relevant. A classic example is a live search feature. When a user enters text, a request is dispatched to a server, and since this is asynchronous, the outcome arrives as an observable. Now, what if the user modifies the search text before the initial response returns? A second request, with the updated text, is sent out, resulting in two outstanding server calls. The response for the first query, though, holds results that are now obsolete. Merging that stale result with the new one would lead to confusion and a poor user experience. This is precisely where switchAll proves valuable by subscribing exclusively to the most recent inner observable sequence and disregarding any that came before.
The following example demonstrates how to use switchAll to dynamically switch between two streams:
const a = interval(500).pipe(map((v) => 'a' + v), take(3));
const b = interval(500).pipe(map((v) => 'b' + v), take(3));
const higherOrderObservable = interval(1000).pipe(take(2), map(i => [a, b][i]));
higherOrderObservable.pipe(switchAll()).subscribe((value) => console.log(value));
