SwitchMap vs mergeMap vs concatMap in Angular: Key Differences and Usage
switchMap cancels previous inner observables and switches to the latest one, mergeMap runs all inner observables concurrently, and concatMap queues inner observables and runs them one after another in order.Quick Comparison
Here is a quick overview of how switchMap, mergeMap, and concatMap behave in Angular RxJS.
| Feature | switchMap | mergeMap | concatMap |
|---|---|---|---|
| Execution | Cancels previous inner observable, switches to latest | Runs all inner observables concurrently | Queues inner observables, runs one at a time in order |
| Order | Only latest result emitted | Results can come in any order | Results emitted in order of requests |
| Use case | When only latest result matters (e.g., autocomplete) | When all results matter and can run in parallel | When order matters or to avoid concurrency |
| Concurrency | 1 active inner observable at a time | Multiple active inner observables | 1 active inner observable at a time |
| Behavior on rapid emissions | Previous requests canceled | All requests processed simultaneously | Requests processed sequentially |
Key Differences
switchMap is best when you want to ignore previous inner observable results and only care about the latest one. It cancels any ongoing inner observable when a new value arrives, making it ideal for scenarios like search autocomplete where only the newest input matters.
mergeMap subscribes to every inner observable immediately and merges their outputs. It allows multiple inner observables to run concurrently, so all results are processed regardless of order. This is useful when you want to handle all events, like multiple API calls triggered by user actions.
concatMap queues inner observables and runs them one after another, preserving the order of emissions. It waits for the current inner observable to complete before starting the next. This is helpful when order matters or when you want to avoid overloading resources by running many observables at once.
Code Comparison
This example shows how switchMap handles a stream of clicks by canceling previous inner observables and only emitting the latest result.
import { fromEvent, interval } from 'rxjs'; import { switchMap, take } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe( switchMap(() => interval(1000).pipe(take(3))) ); result.subscribe(x => console.log('switchMap:', x));
mergeMap Equivalent
This example uses mergeMap to handle the same clicks but runs all inner intervals concurrently without canceling any.
import { fromEvent, interval } from 'rxjs'; import { mergeMap, take } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe( mergeMap(() => interval(1000).pipe(take(3))) ); result.subscribe(x => console.log('mergeMap:', x));
When to Use Which
Choose switchMap when you only want the latest result and want to cancel previous ongoing tasks, such as live search or autocomplete.
Choose mergeMap when you want to process all tasks concurrently and don't want to cancel any, like handling multiple independent API calls.
Choose concatMap when order matters or you want to run tasks one by one to avoid concurrency issues, such as saving data sequentially.
Key Takeaways
switchMap cancels previous inner observables and emits only the latest result.mergeMap runs all inner observables concurrently and merges their results.concatMap queues inner observables and runs them sequentially in order.switchMap for latest-only scenarios, mergeMap for parallel processing, and concatMap for ordered or sequential tasks.