21

Given such observable

Rx.Observable.of([1,2,3,4,5])

which emits a single item (that is an array), what is the operator that will transform this observable to a one that emits 5 single items (or whatever the array consists of)?

The example is on .of, but it would be the same for fetching arrays via promises, there might be many other examples. Don't suggest to replace of with from

ducin
  • 25,621
  • 41
  • 157
  • 256

5 Answers5

17

I can't think of an existing operator to do that, but you can make one up :

arrayEmitting$.concatMap(arrayValues => Rx.Observable.merge(arrayValues.map(Rx.Observable.of)))

or the simpler

arrayEmitting$.concatMap(Rx.Observable.of)

or the shortest

arrayEmitting$.concatMap(x => x)

That is untested so let me know if that worked for you, and that uses Rxjs v4 API (specially the last one). This basically :

  • process each incoming array of values as one unit (meaning that the next incoming array will not interlap with the previous one - that is why I use concatMap)
  • the incoming array is transformed into an array of observables, which are merged : this ensures the emission of values separately and in sequence
user3743222
  • 18,345
  • 5
  • 69
  • 75
  • hmm, that makes sense what you wrote :) but it's strange that there's no operator for this. If you had to fetch data via AJAX/promise and the data happens to be an array of items - and you want to emit each of these items separately - would you do above? – ducin Apr 07 '17 at 16:54
  • you can simplify by by directly applying `.of ` but I thought you said you did not want to do that, i.e. `arrayEmitting$.concatMap(Rx.Observable.of)` – user3743222 Apr 07 '17 at 16:57
  • 3
    `.concatMap(x => x)` - that's the answer! – ducin Apr 07 '17 at 17:08
9

You can also use the flatMap operator (https://stackoverflow.com/a/32241743/3338239):

Observable.of([1, 2, 3, 4])
  .flatMap(x => x)
  .subscribe(x => console.log(x));
// output:
// 1
// 2
// 3
// 4
Marten S
  • 482
  • 7
  • 8
8

You can use from now to convert an array into a sequence.

https://www.learnrxjs.io/operators/creation/from.html

from([4,5,6])

Joey V.
  • 1,866
  • 1
  • 22
  • 18
4

mergeAll:

Observable.of([4, 5, 6])
  .mergeAll()
  .subscribe(console.log);
// output:
// 4
// 5
// 6
Fabricio
  • 7,705
  • 9
  • 52
  • 87
3

Dont understand why concatMap(x => x) or flatMap(x => x) works, it doesnt change anything. This should work (rxjs 6 or above):

of([4,5,6]).pipe(mergeMap(from))
dttung1412
  • 93
  • 1
  • 2
  • 8