How to Use switchMap in RxJS: Syntax and Examples
Use
switchMap in RxJS to map each value from a source observable to a new inner observable, automatically cancelling the previous inner observable if a new value arrives. This helps handle asynchronous operations like HTTP requests by switching to the latest observable and ignoring older ones.Syntax
The switchMap operator takes a function that returns an observable. It subscribes to this inner observable and emits its values. If a new value comes from the source observable, switchMap unsubscribes from the previous inner observable and switches to the new one.
- sourceObservable: The original observable emitting values.
- switchMap(fn): The operator that maps each source value to a new observable.
- fn(value): A function returning an inner observable based on the source value.
typescript
sourceObservable.pipe( switchMap(value => innerObservable) )
Example
This example shows how switchMap handles user search input by cancelling previous HTTP requests and only processing the latest one.
typescript
import { of, fromEvent } from 'rxjs'; import { switchMap, debounceTime, distinctUntilChanged, map, delay } from 'rxjs/operators'; // Simulated HTTP request returning observable function fakeHttpRequest(query: string) { return of(`Results for "${query}"`).pipe( // simulate network delay delay(500) ); } // Simulate user typing in a search box const searchBox = document.createElement('input'); document.body.appendChild(searchBox); fromEvent(searchBox, 'input').pipe( map((event: Event) => (event.target as HTMLInputElement).value), debounceTime(300), distinctUntilChanged(), switchMap(query => fakeHttpRequest(query)) ).subscribe(result => { console.log(result); });
Output
Results for "a"
Results for "ab"
Results for "abc"
Common Pitfalls
Not cancelling previous inner observables: Using mergeMap instead of switchMap can cause multiple inner observables to run simultaneously, leading to outdated results.
Forgetting to return an observable: The function inside switchMap must return an observable, not a plain value.
typescript
import { of } from 'rxjs'; import { mergeMap, switchMap } from 'rxjs/operators'; // Wrong: mergeMap allows multiple inner observables source$.pipe( mergeMap(value => of(value)) ); // Right: switchMap cancels previous inner observables source$.pipe( switchMap(value => of(value)) );
Quick Reference
- Use switchMap when you want to cancel previous async tasks and only keep the latest.
- Returns values from the latest inner observable.
- Common use cases: HTTP requests, autocomplete, typeahead search.
- Do not use if you want to keep all inner observables active (use mergeMap instead).
Key Takeaways
switchMap maps each source value to a new observable and cancels the previous one automatically.
Use switchMap to handle async operations like HTTP requests where only the latest result matters.
The function inside switchMap must return an observable, not a plain value.
Avoid using mergeMap when you want to cancel previous inner observables to prevent outdated data.
switchMap is ideal for user input scenarios like search autocomplete to avoid race conditions.