Angular HTTP Interceptor - Display spinner in multi-module app

后端 未结 4 1512
既然无缘
既然无缘 2020-12-30 11:01

I\'m trying to display the ng4-loading-spinner spinner for HTTP calls made to my API.

I based my code on the examples in the following links:

相关标签:
4条回答
  • 2020-12-30 11:41

    The issue was the ApiService was using the Http from @angular/http instead of HttpClient from @angular/common/http.

    So the ApiInterceptor has nothing to intercept.

    0 讨论(0)
  • 2020-12-30 11:46

    For anyone who has the problem with the counter never reaching zero again, even though no requests are pending: I had to additionaly check for the type of event when increasing the counter:

     if (event instanceof HttpResponse) {
        this.counter.dec();
     } else {
        this.counter.inc();
     }
    

    Otherwise, i had the case of a HttpResponse also increasing my counter. With the above check my counter is going back to zero on all my components.

    Also, make sure a returning http error (e.g. 401) is also decreasing your counter, otherwise the counter will never reach zero again. To do so:

    return next.handle(req).pipe(tap(
      (event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
            this.counter.dec();
        }
      },
      err => {
        if (err instanceof HttpErrorResponse) {
          this.counter.dec();
        }
      }
    ));
    
    0 讨论(0)
  • 2020-12-30 11:54

    forget reportProgress:true. The problem is that we have to discriminate the event of "do". Moreover, we must take a count of the calls, so the interceptor must be like

    contador: number = 0;
    
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            this.contador++;
            if (this.contador === 1) {
                this.spinner.show();
            }
            let handleObs: Observable<HttpEvent<any>> = next.handle(req);
            handleObs
            .catch((err: any) => { //If an error happens, this.contador-- too
                this.contador--;
                return Observable.throw(err);
            })
            .do(event => {
               if (event instanceof HttpResponse) { //<--only when event is a HttpRespose
                  this.contador--;
                  if (this.contador==0)
                     this.spinner.hide();
               }
            });
    
            return handleObs;
        }
    
    0 讨论(0)
  • 2020-12-30 12:03

    For everyone following up to this issue, the OP's code now is working fine, except for the remaining issue that the loader doesn't seem to hide. The fix to that is to subscribe to the Observable, after the .catch .do chain, like so:

    handleObs
        .catch((err: any) => {
            this.count--;
            return Observable.throw(err);
        })
        .do(event => {
            if (event instanceof HttpResponse) {
                this.count--;
                if (this.count == 0) this.spinner.hide();
            }
        })
        .subscribe(); /* <---------- ADD THIS */
    
    return handleObs;
    

    After this, the code should be working fine, and the loader will hide when the counter reaches 0. Thanks to all the above answers for their contribution as well!

    0 讨论(0)
提交回复
热议问题