Why do we need to use flatMap?

user233232 picture user233232 · Nov 2, 2015 · Viewed 106.8k times · Source

I am starting to use RxJS and I don't understand why in this example we need to use a function like flatMap or concatAll; where is the array of arrays here?

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(url => {console.log(url)})

If someone can visually explain what is happening, it will be very helpful.

Answer

serkan picture serkan · Nov 17, 2016
['a','b','c'].flatMap(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//['a', 'ax', 'ay', 'az', 'b', 'bx', 'by', 'bz', 'c', 'cx', 'cy', 'cz']


['a','b','c'].map(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//[Array[4], Array[4], Array[4]]

You use flatMap when you have an Observable whose results are more Observables.

If you have an observable which is produced by an another observable you can not filter, reduce, or map it directly because you have an Observable not the data. If you produce an observable choose flatMap over map; then you are okay.

As in second snippet, if you are doing async operation you need to use flatMap.

var source = Rx.Observable.interval(100).take(10).map(function(num){
    return num+1
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>

var source = Rx.Observable.interval(100).take(10).flatMap(function(num){
    return Rx.Observable.timer(100).map(() => num)
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>