Home > Back-end >  Using rxjs finalize
Using rxjs finalize

Time:12-16

I have the following rxjs stream:

this.universities$ = this.activatedRoute.queryParams.pipe(
        switchMap((obj: any) => this.httpService.getUniversitiesList(this.numberOfRows, new URLSearchParams(obj).toString()).pipe(
          tap((res: any) => {
  
            this.totalPages = res.pagination.total;

            
            if ((res.pagination.current_page > 1)){
              setTimeout(() => this.paginator.changePage(res.pagination.current_page - 1));
            }

          })
        ).pipe(
          startWith(null)
        ))
      );

At the moment I have that rather ugly setTimeout which sets PrimeNG's paginator number. Without it, I'd be trying to set it before the data is ready and therefore the number won't be set.

From what I've read I need to use the rxjs operator finalize to do this properly. But I'm unsure where to place that. Do I need to pipe and switchMap after the tap?

CodePudding user response:

This answer seems to work using the first property for the primeng paginator. Stackblitz

I've split the getting of total pages and first into separate streams. Using share() prevents hitting api twice.

@Component({
  selector: 'my-app',
  template: `
  <p-paginator
    [rows]="pageSize"
    [totalRecords]="totalPages$ | async"
    [first]="first$ | async"
    >
  </p-paginator>
  `,
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  totalPages$: Observable<number> = of();
  pageSize = 10;
  first$: Observable<number> = of();

  ngOnInit() {
    const data$ = mockGetUniversitiesList().pipe(
      tap((res) => console.log(`Got data...${JSON.stringify(res)}`)),
      share()
    );

    // get total pages
    this.totalPages$ = data$.pipe(map((res) => res.pagination.total));

    // change page
    this.first$ = data$
      .pipe(
        map((res) => res.pagination.current_page - 1),
        filter((page) => page > 1),
        map(page =>  page * this.pageSize)
      )
  }
}

Note I don't use primeng so answer may need adapting

CodePudding user response:

I would suggest to use tap logic in place where are you subscribing to this.universities$, since this.universities$ is a observable of universities data and only, and shouldn't have any another side-effects

I would suggest to do it in this way

this.universities$.subscribe(() => {
  this.resetPagination();
});

It might not fix your problem but code style will be more correct

  • Related