Best way to "flatten" an array inside an RxJS Observable

45,808

Solution 1

Actually if you need it inside the stream just use this:

.flatMap(items => of(...items))

Solution 2

If it is a synchronous operation, I would suggest to use javascript's Array.map instead, it even should save you some performance:

const dataFromBackend = Rx.Observable.of([
  { name: 'item1', active: true },
  { name: 'item2', active: false },
  { name: 'item3', active: true }
]);

dataFromBackend
  .map(items => items.map(item => item.name))
  .subscribe();
Share:
45,808
AngularChef
Author by

AngularChef

Formations et tutos Angular en français - https://www.angularchef.com/

Updated on May 14, 2020

Comments

  • AngularChef
    AngularChef about 4 years

    My backend frequently returns data as an array inside an RxJS 5 Observable (I'm using Angular 2).

    I often find myself wanting to process the array items individually with RxJS operators and I do so with the following code (JSBin):

    const dataFromBackend = Rx.Observable.of([
      { name: 'item1', active: true },
      { name: 'item2', active: false },
      { name: 'item3', active: true }
    ]);
    
    dataFromBackend
      // At this point, the obs emits a SINGLE array of items
      .do(items => console.log(items))
      // I flatten the array so that the obs emits each item INDIVIDUALLY
      .mergeMap(val => val)
      // At this point, the obs emits each item individually
      .do(item => console.log(item))
      // I can keep transforming each item using RxJS operators.
      // Most likely, I will project the item into another obs with mergeMap()
      .map(item => item.name)
      // When I'm done transforming the items, I gather them in a single array again
      .toArray()
      .subscribe();
    

    The mergeMap(val => val) line doesn't feel very idiomatic.

    Is there a better way to apply transformations to the members of an array that's emitted by an Observable?

    NB. I want RxJS operators (vs array methods) to transform my items because I need the ability to project each item into a second observable. Typical use case: backend returns of list of item ids and I need to request all of these items from the backend.