I have an intercept that listens requests/responses.
I have tried to run spinner only if requests comes more then 1 seconds:
@Injectable()
export class LoadingInterceptor implements HttpInterceptor {
private requests: HttpRequest<any>[] = [];
constructor(private spinnerService: SpinnerService) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
this.requests.push(req);
this.spinnerService.isLoading.next(true);
return new Observable((observer) => {
next.handle(req).subscribe(
(event) => {
if (event instanceof HttpResponse) {
this.removeRequest(req);
observer.next(event);
}
},
() => {
this.removeRequest(req);
},
() => {
this.removeRequest(req);
}
);
});
}
private removeRequest(request: HttpRequest<any>) {
const index = this.requests.indexOf(request);
if (index >= 0) {
this.requests.splice(index, 1);
}
this.spinnerService.loadingStop.next();
this.spinnerService.loadingStop.complete();
this.spinnerService.isLoading.next(this.requests.length > 0);
}
}
Spinner service is:
constructor() {
this.isLoading
.pipe(debounceTime(100), delay(1000), takeUntil(this.loadingStop))
.subscribe((status: boolean) => (this.loadingStatus = status));
}
For that I have added this:
.pipe(debounceTime(100), delay(1000), takeUntil(this.loadingStop))
But it does not work for me...How to show spinner if response comes more 1 second?
To prevent the flickering of the loading indicator (I omitted the handling of multiple requests).
debounceTime(500) in spinner service does the trick:
The component to see this in action:
HTML:
The solution via an interceptor is somewhat coarse grained. At some point you might need a finer grained solution. E.g. to show a loading indicator for multiple parallel requests/components. Another solution is given in Nil's blog post.
There are plenty solutions to your problem. Hope it helps.
Uses the iif operator to stop loading instantly.
this is what the interceptor should look like:
this is the loading service:
and so it should look in the template