Show Buttons
Share On Facebook
Share On Twitter
Share On Google Plus
Share On Linkdin
Share On Reddit
Share On Stumbleupon
Contact us
Hide Buttons

The difference between switchMap and flatMap or mergeMap

switchMap and mergeMap are probably going the be the most powerful and frequently used operators in your arsenal. Its is thereby critical to understand the difference between the two in order to spend less time debugging code. Both switchMap and mergeMap are used to flatten observables. mergeMap is also known as flatMap, however throughout this article, I will be be referring to it as mergeMap.

TIP> I usually like runing my examples in the browser console of http://reactivex.io/rxjs/. The added advantage is that I get some nice autocomplete for looking up method names.

The easiest way to remember the difference between mergeMap and switchMap is

When you hear the word merge, think – use everything on all the streams aka. merge everything. Whereas when you hear the word switch, think – switch to using data on the newer stream

The difference is subtle yet important. Lets demonstate with some examples.

mergeMap

var outer = Rx.Observable.interval(1000).take(2);

var source = outer.mergeMap(function (x) {
  return Rx.Observable.interval(500).take(3).map(y => `${x}:${y}`)
});

source.subscribe(d => console.log(d));

Marble diagram

// Marble Diagram
/*
source: -0-------1|
          \       \
inner2:    \       0---1---2|  
            \
inner1:      0---1---2|

    mergeMap()

output: -----x---x-x-x-x---x|
*/

There are few things to remember here.

1) We are returning an observable stream from within an operator function. Thats precisely why we need to flatten using mergeMap (and as we will see later, switchMap).
2) Two inner streams are emitting data concurrently. One stream starts after the other.
3) Data is available on the ouput corresponding to EVERY value emmitted on ALL the inner streams. i.e. No data is ever lost.

Keeping these three points in mind, now lets rewrite the above example using switchMap

switchMap

var outer = Rx.Observable.interval(1000).take(2);

var source = outer.switchMap(function (x) {
  return Rx.Observable.interval(500).take(3).map(y => `${x}:${y}`)
});

source.subscribe(d => console.log(d));

Marble diagram

// Marble Diagram
/*
source: -0-------1|
          \       \
inner2:    \       0---1---2|  
            \
inner1:      0---1---2|

    switchMap()

output: -----x-----x---x---x|
*/

Notice this time how the output has far fewer data points. Thats because the moment the inner2 stream became available, the output no longer listens to data from inner1. switchMap effectively switches over to inner2 and unsubscribes from the previous one.

This also implies that even though the inner streams may be producing data concurrently in switchMap, the output is only determined by the latest observable that is still producing data.

Hope this simplifies your understanding of these two operators.

Ryan Sukale

Ryan is just a regular guy next door trying to manage his life and finances.

You may also like...

  • Farhad

    Thanks. now it makes sense 🙂

  • STAT

    Thanks a lot. It’s the best explanation I found. Now I understand.

  • tutorialhorizon

    Glad the quote helped. It took me a while to understand it as well.

  • tutorialhorizon

    You’re welcome! I am so happy to learn that all the time I put into writing this article is helping people make the right choices.

  • SnoozeFace

    Great explanation.

  • Westor

    Good article, but I think, the output in this case would be more like soccer results 0:0 0:1 etc 🙂