How to get data in chunks from an API using rxjs interval and stop when there is no data left

1k Views Asked by At

I am trying to load data in chunks on timely basis. for this I am using thee methods.

This function loads data from a json object that I am using to mimic api data

 getScrollingData(startIndex, endIndex){
    if(this.items.data.length>endIndex){
      return of(this.items.data.slice(startIndex, endIndex));
    }else{
      return of(null)
    }
  }

The getData method below is being used to send request every two seconds

getData(){
const secondsCounter = interval(2000); 
return secondsCounter
.pipe(
  flatMap((res) => {
    if(res!=null)
     return this.mimicApiService.getScrollingData(res, res+10)
            .takeUntil(v => v != null)// this causes error
  }),
  
  
)

}

In the ngOnInit of component I am subscribing to getData to load that data into array to be displayed on the screen

data = [];
ngOnInit() {
  this.dataService.getData().subscribe((res)=>{
    this.data = [...this.data, ...res];
  });
}

Questions

  1. I am getting error Argument of type '(v: any) => boolean' is not assignable to parameter of type 'Observable<any>' from takeUntil. Can you please tell why this happens?
1

There are 1 best solutions below

1
On

You are using the wrong operator, takeUntil wants an observable and will stop taking once that observable emits.

What you need is takeWhile, which suits your use case better:

takeWhile(v => v != null)

and here is the doc

Edit: if you also want to stop the interval when there is no more data returned from getScrollingData, you can do something like the following:

getData() {
  const stopInterval = new Subject();
  const secondsCounter = interval(2000)
    .pipe(takeUntil(stopInterval));
  return secondsCounter
    .pipe(
      flatMap((res) => {
        if (res != null)
          return this.getScrollingData(res, res + 2)
      }),
      takeWhile(v => {
        if (v == null) {
          stopInterval.next();
          return false;
        }
        return true;
      }))
}

once we emit from stopInterval, takeUntil of interval will trigger.