angulartypescriptrxjs

Replacing a nested subscribe when getting multiple details from one initial call for ids


So I'm making a few calls to two back-end services, the first is to get the IDs of "big" items and the rest are separate calls to get the details of each "big" item using its ID.

I've looked at the concatMap(), switchMap(), mergeMap(), etc. from a great post here (and others): Rxjs One Observable Feeding into Another but I never seem to find where I can insert my loop to gather the data from an unknown number of calls to the second collection.

So here's the current way that works, but I want to move away from sub-in-sub.

Is this a job for Promises instead of RxJS?

loadWigitsDetailed() {
  this.wigitGetterService
    .fetchWigitIds({
      category: 'big'
    })
    .subscribe(response => {
      // say, 5 items returned.
      for (const oneWig of response.items) {
        this.detailedWigitInfoService.fetchWigitInfo({ id: oneWig.id })
          .subscribe(responseDetail => {
            wigitTable.addRow(responseDetail);
          });
      }
    });
}

Solution

  • You can definitely use Promises for this. But you could also use RxJS for this well. It can be done like this:

    loadWigitsDetailed() {
      this.wigitGetterService.fetchWigitIds({ category: 'big' })
        .pipe(
          // Flatten the items array into a stream of items
          mergeMap(response => response.items),
          // For each item, fetch the detailed info
          mergeMap(eachWig => this.detailedWigitInfoService.fetchWigitInfo({ id: eachWig.id }))
        )
        .subscribe(responseDetail => {
          wigitTable.addRow(responseDetail);
        });
    }
    
    

    mergeMap should be used if the order is not important. But if you want things to go in a specific order, then you can replace mergeMap with concatMap.