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 prob­a­bly going the be the most pow­er­ful and fre­quently used oper­a­tors in your arse­nal. Its is thereby crit­i­cal to under­stand the dif­fer­ence between the two in order to spend less time debug­ging code. Both switchMap and mergeMap are used to flat­ten observ­ables. mergeMap is also known as flatMap, how­ever through­out this arti­cle, I will be be refer­ring to it as mergeMap.

TIP> I usu­ally like run­ing my exam­ples in the browser con­sole of http://reactivex.io/rxjs/. The added advan­tage is that I get some nice auto­com­plete for look­ing up method names.

The eas­i­est way to remem­ber the dif­fer­ence between mergeMap and switchMap is

When you hear the word merge, think — use every­thing on all the streams aka. merge every­thing. Whereas when you hear the word switch, think — switch to using data on the newer stream

The dif­fer­ence is sub­tle yet impor­tant. Lets demon­state 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 remem­ber here.

1) We are return­ing an observ­able stream from within an oper­a­tor func­tion. Thats pre­cisely why we need to flat­ten using mergeMap (and as we will see later, switchMap).
2) Two inner streams are emit­ting data con­cur­rently. One stream starts after the other.
3) Data is avail­able on the ouput cor­re­spond­ing to EVERY value emmit­ted on ALL the inner streams. i.e. No data is ever lost.

Keep­ing these three points in mind, now lets rewrite the above exam­ple 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 out­put has far fewer data points. Thats because the moment the inner2 stream became avail­able, the out­put no longer lis­tens to data from inner1. switchMap effec­tively switches over to inner2 and unsub­scribes from the pre­vi­ous one.

This also implies that even though the inner streams may be pro­duc­ing data con­cur­rently in switchMap, the out­put is only deter­mined by the lat­est observ­able that is still pro­duc­ing data.

Hope this sim­pli­fies your under­stand­ing of these two operators.

Ryan Sukale

Ryan is a UX engineer living in San Francisco, California.

You may also like...