Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show spinner only for long time requests with Angular HttpInterceptor

I created an interceptor to show a spinner when an HTTP request is made:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { NgxSpinnerService } from 'ngx-spinner';
import { Observable } from 'rxjs/Observable';
import { finalize } from 'rxjs/operators';

@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {

  constructor(
    private spinner: NgxSpinnerService
  ) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.spinner.show();

    return next.handle(req).pipe(finalize(() => this.spinner.hide()));
  }

}

I'm using ngx-spinner for that purpose.

I want to show the spinner only for HTTP requests that take more than 1 second, for example. I've been trying to use debounceTime but I'm not sure how to use it or if it's suitable for what I want.

Is there any way to do this using the interceptor?

UPDATE: I came to the solution after opening the question, it's very similar to @joyBlanks answer, this is what I did:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  let finished = false;

  setTimeout(() => {
    if (!finished) {
      this.spinner.show();
    }
  }, 1000);

  return next.handle(req).pipe(finalize(() => {
    finished = true;
    this.spinner.hide();
  }));
}
like image 324
Alavaros Avatar asked Oct 22 '25 09:10

Alavaros


1 Answers

Set a timer to show spinner after 1 sec.

If the request is completed < 1s you will never see it else it will be hidden if it is shown.

timer: NodeJS.Timeout;
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if(this.timer){
    clearTimeout(this.timer);
  }
  this.timer = setTimeout(() => this.spinner.show(), 1000);

  return next.handle(req).pipe(finalize(() => {
    this.spinner.hide();
    if(this.timer){
      clearTimeout(this.timer);
    }
  }));
}
like image 63
joyBlanks Avatar answered Oct 26 '25 05:10

joyBlanks