Search code examples
angularrxjsobservable

Angular RxJS add data from new observable to current observable


So, I have list$ as an observable[]. I'm using async in the template to subscribe to it.

When I scroll I call this method.

onScroll() {
    this.list$ = this.list$?.pipe(
      tap((list) => {
        this.notificationService
          .getNotificationListForUser(`?PageIndex=${++this.pageIndex}`)
          .subscribe((e) => {
            list.push(...e);
          });
      })
    );
  }

So what I do is I push new values to the existing list array and that's what I want, but I think that my code is not clear and I do not know which RxJS operators to use to refactor my code. So I need to refactor this code with RxJS operators...


Solution

  • Everytime onScroll is called you will add an extra tap into the pipe so by page 20 your tap will run 20 times. You should not reassign observable references, you should make existing observables emit new values.

    Use a behavior subject for the page index and increment it on onScroll, then switchMap from the behavior subject to notifications. Then use a scan to collect the values.

    pageIndex$ = new BehaviorSubject(1);
    
    list$ = pageIndex$.pipe(
      switchMap(pageIndex => this.notificationService.getNotificationListForUser(`?PageIndex=${pageIndex}`)),
      scan((list, items) => [...list, ...items], [])
    );
    
    onScroll() {
      this.pageIndex$.next(this.pageIndex$.value + 1);
    }
    

    Then use list$ with the async pipe in your template.

    <ng-container *ngFor="let item of (list$ | async)">
      {{ item | json }}
    </ng-container>