rxjs angular call webservice until condition met

joachim_b

I have a list of objects and want to call a webservice for the first n objects. The api call returns the size of the object and I want to call until the total size sum reaches a threshold. My code so far:

const stop$: Subject<any> = new Subject();
this.totalFileSize = 0;
from(this.entities) // entities is an array of object with an id
  .pipe(
    mergeMap((e) => 
      this.adminService.AdminTasksGetWebMetrics(e.id) // get the size of one object
    ),
    takeUntil(stop$),
    tap(result=>{
      this.totalFileSize += result.Item.TotalSize;
      if(this.totalFileSize>this.fGroup.get('BatchSize').value*1000000000){
        stop$.complete();
      }else{
        stop$.next(1);
      }
    }),
...

Problem is that mergeMap will already send requests for all entities before the condition is checked. How would I achieve to test after each api call?

BizzyBob

You could specify the concurrency parameter with mergeMap, limiting the number of active api calls:

from(this.entities).pipe(
  mergeMap(e => this.adminService.AdminTasksGetWebMetrics(e.id), 3)
  ...
);

This would not completely prevent excessive calls, but could greatly limit them. You could, of course use concurrency = 1 (aka, concatMap) which would eliminate excessive calls.

Also, instead of using a Subjectand keeping track of the total file size inside tap, you could utilize the scan operator, to keep track of the accumulated file size:

from(this.entities).pipe(
  concatMap(e => this.adminService.AdminTasksGetWebMetrics(e.id)),
  scan((total, size) => total + size, 0),
  takeWhile(totalSize => totalSize < this.fGroup.get('BatchSize').value*1000000000)
);

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related