Search code examples
angularrxjsangularfire2rxjs6

RxJs Observable in Observable from Array


I'm working with angularfire and I'm getting a continuous stream of arrays with mission ids in it. I need to fetch the mission document of each id in the array as a new observable. Then return an array of mission docs into the stream so that I'll be able to subscribe to it in my component and display a list of missions.

So far I got it to work with mergeMap. I split the array and fetch the mission docs and return them into the stream. Only problem with my solution is, that when I subscribe to the Observable I don't get an array of missions but every mission as a single change which I can not loop with ngFor. using the toArray() operator does in this case not work, because its a continuous stream which never ends.

This is my code so far:

this.db.collection(`games/${gameId}/missions`).valueChanges().pipe(
    mergeMap(missions => missions),
    mergeMap((mission: any) => {
        return this.db.doc(`missions/${mission.id}`).snapshotChanges();              
    }),
);

This generates the following output in single events:

{ id: 1, missionProperties }
{ id: 2, missionProperties }
{ id: 3, missionProperties }

But I would like to have it in one event as array of missions:

[
    { id: 1, missionProperties },
    { id: 2, missionProperties },
    { id: 3, missionProperties }
]

Solution

  • use the scan operator to aggregate

    this.db.collection(`games/${gameId}/missions`).valueChanges().pipe(
      switchMap(missions =>
          from(missions).pipe(
            mergeMap(mission => this.db.doc(`missions/${mission.id}`).snapshotChanges()),
           scan((acc, curr) => [curr, ...acc], [])
          ),
    )