How to Use mergeMap in RxJS: Syntax, Example, and Tips
mergeMap operator in RxJS maps each value from a source observable to an inner observable and merges all inner observables into a single observable. It is useful for handling multiple asynchronous tasks concurrently without waiting for each to complete before starting the next.Syntax
The mergeMap operator takes a function that returns an observable for each value emitted by the source observable. It subscribes to all inner observables and merges their outputs into one observable stream.
- sourceObservable.pipe(mergeMap(value => innerObservable)): Transforms each source value into an inner observable.
- value => innerObservable: Function returning an observable for each source value.
- All inner observables run concurrently and their results are merged.
import { of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; const source$ = of(1, 2, 3); const result$ = source$.pipe( mergeMap(value => of(`Result: ${value}`)) ); result$.subscribe(console.log);
Example
This example shows how mergeMap handles multiple asynchronous calls concurrently. Each number from the source observable triggers a simulated API call that returns after a delay. The results appear as soon as each inner observable completes, regardless of order.
import { of } from 'rxjs'; import { mergeMap, delay } from 'rxjs/operators'; const source$ = of(1, 2, 3); function fakeApiCall(id: number) { return of(`Response from API ${id}`).pipe(delay(1000 - id * 200)); } source$ .pipe(mergeMap(id => fakeApiCall(id))) .subscribe(console.log);
Common Pitfalls
1. Confusing mergeMap with switchMap: mergeMap runs all inner observables concurrently, while switchMap cancels previous inner observables when a new value arrives.
2. Uncontrolled concurrency: Using mergeMap without limits can cause too many concurrent subscriptions, leading to performance issues.
3. Forgetting to return an observable: The function inside mergeMap must return an observable, not a plain value.
import { of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; const source$ = of(1, 2, 3); // Wrong: returns a plain value instead of observable const wrong$ = source$.pipe( mergeMap(value => `Value: ${value}`) // This will cause an error ); // Right: returns an observable const right$ = source$.pipe( mergeMap(value => of(`Value: ${value}`)) ); right$.subscribe(console.log);
Quick Reference
| Feature | Description |
|---|---|
| Purpose | Maps each source value to an inner observable and merges all outputs |
| Concurrency | Runs all inner observables concurrently without canceling |
| Return value | An observable that emits merged results from all inner observables |
| Common use case | Handling multiple async requests simultaneously |
| Difference from switchMap | Does not cancel previous inner observables |
Key Takeaways
mergeMap to handle multiple async tasks concurrently by merging inner observables.mergeMap function to avoid errors.mergeMap does not cancel previous inner observables, unlike switchMap.mergeMap when you want all inner observables to run and emit results independently.