Avneesh
Avneesh

Reputation: 149

Handle multiple http requests and wait for all to complete using Angular RxJs Observables

I am using Observables, I have a use case where:

  1. I have to get "pages" from service which gives me Page[]
  2. For each of those "pages" I have to get the "sections" from other service
  3. Also on subscribe of all those "sections" I have to do some action based on the data returned.

The concern is once all of those requests are completed then have to do some action.

Upvotes: 7

Views: 15875

Answers (2)

CharanRoot
CharanRoot

Reputation: 6325

you need use mergeMap and forkJoin

When using forkJoin you can fire parallel request at the same time and it will wait till all requests are completed.

this.http.get('/api/pages/')
    .map((res: any) => res.json())
    .mergeMap((pages: any[]) => {
      if (pages.length > 0) {
        return Observable.forkJoin(
          pages.map((page: any) => {
            return this.http.get('/api/sections/' + page_id)
              .map((res: any) => {
                let section: any = res.json();
                // do your operation and return
                return section;
              });
          });
        );
      }
      return Observable.of([]);
    });
}

Upvotes: 11

martin
martin

Reputation: 96891

In general when nesting async calls try to stay as flat as possible. Otherwise, you're creating callback hell which make things even more complicated than just with regular iterative code:

this.http.get('/api/pages/')
  .map((res: Response) => res.json())
  .concatMap((pages: Page[]) => {
    const observables = pages.map(p => this.http.get('whatever' + p.id));

    return Observable.forkJoin(observables, (...results) => 
      results.map((result, i) => {
        pages[i].sections = result;
        return pages[i];
      })
    )
  })
  .subscribe(pagesWithSections => ...);

The forkJoin() operator takes as argument a selector function that lets you work with the results of all the source Observables. I'm using it to update the original pages array and return it.

Upvotes: 8

Related Questions