map vs switchMap in RxJS
Map - It acts relatively similar to map in Arrays. map
takes in every value emitted from the Observable
, performs an operation on it.
Jsfiddle example -
var observable = Rx.Observable.interval(1000);
var observer = {
next: function(value) {
console.log(value);
}
};
observable.map(function(value) {
return value*10;
}).subscribe(observer);
SwitchMap - switchMap will subscribe to all the inner Observables inside the outer Observable but it does not merge the inner Observables. It instead switches to the latest Observable and passes that along to the chain.
Let’s assume that each orange vertical line at the top represents 1 second. This means that the outer Observable (OO) emits values at 1, 4, and 5.5 seconds while the inner Observable (IO) emits values every second for 3 seconds, starting immediately after subscription (time zero).
The first three output values (10, 10, 10) seem pretty easy. Just multiply 1 x 10 = 10 for each of them according to the operator logic. Based on these first three values, we could say that for each OO value, the IO emits all of its values.
This assumption seems to hold true for the first output value of 30… And the second output value of 30…
But shouldn’t it emit a final value of 30??
This is where the switchMap logic comes in. Every time the OO emits a value, the IO emits all of its values unless the OO emits a new value before the IO finishes emitting all of its values. We can see this when the OO emits a value of 5 and it appears that our last value of 30 is “canceled”.
Projects each source value to an Observable which is merged in the output Observable, emitting values only from the most recently projected Observable.
Jsfiddle example -
var button = document.querySelector('button');
var obs1 = Rx.Observable.fromEvent(button, 'click');
var obs2 = Rx.Observable.interval(1000);
obs1.switchMap(
event => {
return obs2
}
).subscribe(
(value) => console.log(value)
);
In above example, no matter how many time I click the button, I am always going to get the values starting from 0 because switchMap
switches to the latest observable.
Best use case is when we want to make an API call based on data received from outer observable.
Read more -
https://zach-gollwitzer.medium.com/how-to-read-an-rxjs-marble-diagram-f6e8dfa29781 https://dev.to/bhagatparwinder/map-vs-mergemap-vs-switchmap-5gee https://blogs.msmvps.com/deborahk/higher-order-observable/
Both operators are different.
switchMap: Maps values to observable. Cancels the previous inner observable.
Eg:
fromEvent(document, 'click')
.pipe(
// restart counter on every click
// First click: 0, 1, 2...
// Second click: cancels the previous interval and starts new one. 0, 1, 2...
switchMap(() => interval(1000))
)
.subscribe(console.log);
map: Add projection with each value.
Eg:
//add 10 to each value
const example = source.pipe(map(val => val + 10));
Instead of a textual explanation, I always prefer visual explanation.
Map -
switchmap -