Search code examples
angularrxjsangular-materialrxjs-pipeable-operators

merge pipe die after catchError


I've trying to use Angular material paginator and sorting, and get some code from material.angular.io example. This part:

ngOnInit() {
    this.exampleDatabase = new ExampleHttpDao(this.http);

    // If the user changes the sort order, reset back to the first page.
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

    merge(this.sort.sortChange, this.paginator.page)
      .pipe(
        startWith({}),
        switchMap(() => {
          this.isLoadingResults = true;
          return this.exampleDatabase!.getRepoIssues(
            this.sort.active, this.sort.direction, this.paginator.pageIndex);
        }),
        map(data => {
          // Flip flag to show that loading has finished.
          this.isLoadingResults = false;
          this.isRateLimitReached = false;
          this.resultsLength = data.total_count;

          return data.items;
        }),
        catchError(() => {
          this.isLoadingResults = false;
          // Catch if the GitHub API has reached its rate limit. Return empty data.
          this.isRateLimitReached = true;
          return observableOf([]);
        })
      ).subscribe(data => this.data = data);
}

when server return an error and catchError handled it, sorting ang paging stopt to send requests to the server. What's wrong with theirs example?


Solution

  • This is how observable works, in case of onComplete or onError the observable is stopped. If you want it to resume you can add a repeat operator after catchError, your source observable is a hot Observalbe so you don't have to worry about auto infinite loop. Alternatively you can look into repeatWhen operator

    merge(this.sort.sortChange, this.paginator.page)
      .pipe(
        startWith({}),
        switchMap(() => {
          this.isLoadingResults = true;
          return this.exampleDatabase!.getRepoIssues(
            this.sort.active, this.sort.direction, 
            this.paginator.pageIndex).pipe(
              map(data => {
                 // Flip flag to show that loading has finished.
                 this.isLoadingResults = false;
                 this.isRateLimitReached = false;
                 this.resultsLength = data.total_count;
                 return data.items;
             }),
              catchError(() => {
                 this.isLoadingResults = false;
                 this.isRateLimitReached = true;
                 return observableOf([]);
              })
            );
        })
      ).subscribe(data => this.data = data)