Search code examples
angularrxjsmergemap

Multiple API calls based on page size in Angular


API call - getList() => returns 1000 numbers

  • Say 1,2,3...1000

Make 20 API calls by taking above top 20 results

I am trying to do something like this

this.http.get('urlService').mergeMap((ids: number[]) => this.getItems(ids.slice(0, 20))).
  subscribe(newsList => {
    this.dataRecieved.next(newsList);
  })

But its not working somehow


Solution

  • You could use RxJS forkJoin function to combine multiple HTTP requests. It'll emit only when all the observables complete.

    this.http.get('urlService').pipe(
      switchMap((ids: number[]) => forkJoin(ids.slice(0, 20).map(id => this.getItems(id))))
    ).subscribe(newsList => {
      // newsList[0] - response from `this.getItems(1)`
      // newsList[1] - response from `this.getItems(2)`
      ...
      this.dataRecieved.next(newsList);
    });
    

    I am using Array map function to convert the list [1, 2, ..., 20] to a list of HTTP requests [this.getItems(1), this.getItems(2), ..., this.getItems(20)].


    However, beware that this will trigger 20 simultaneous HTTP calls. Most browsers have a hard limit (Chrome - 6) on how many concurrent calls to the same domain could be made. The recommended way to solve this limit issue is to use WebSockets or domain sharding.

    As a workaround from front-end, you could use RxJS bufferCount operator with from function to control the maximum number of parallel requests made at a time.

    this.http.get('urlService').pipe(
      switchMap((ids: number[]) => from(ids.slice(0, 20).map(id => this.getItems(id)))),
      bufferCount(6),                         // <-- adjust number of parallel requests here
      concatMap(buffer => forkJoin(buffer))
    ).subscribe(
      newsList => this.dataRecieved.next(newsList),
      error => // handle error
    );