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:
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.
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();
}
}
));
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;
}
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!