0

I made spinner interceptor for http request. For every http request spinner is showing.

But some web requests are relatively fast, in this case, the spinner will become a flicker in the web page.

I want to make some delay for spinner but i don't have idea how.

Spinner component

<ng-container *ngIf="loading$ | async">
<mat-progress-bar  mode="indeterminate" color='warn'>
</mat-progress-bar>

export class SpinnerComponent implements OnInit {
  loading$;

  constructor(private spinnerService: SpinnerService) { }

  ngOnInit() {
    this.loading$ = this.spinnerService.isLoading$
    .pipe(
     delay(0)
    );
  }

}

Spinner Service

export class SpinnerService {
isLoading$ = new Subject<boolean>();

show() {
    this.isLoading$.next(true);
}
hide() {
    this.isLoading$.next(false);
}

}

Spinner Interceptor

export class SpinnerInterceptor implements HttpInterceptor {
requestCount = 0;
constructor(private spinnerService: SpinnerService) { }

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.requestCount++;
        this.spinnerService.show();

    return next.handle(request)
        .pipe(
            finalize(() => {
                this.requestCount--;
                if (this.requestCount === 0) {
                    this.spinnerService.hide();
                }
            })
        );
}

}

Roni_Droni
  • 35
  • 2
  • 7

3 Answers3

1

You can set a timeout and have code executed after sometime in your hide() function Here's an example

     hide() {
       setTimeout( () => {     
        this.isLoading$.next(false);
       }, 2000 );
     }

There are a couple other methods to achive this, refer to this answer

Kisinga
  • 1,640
  • 18
  • 27
1

You may use debounceTime rxjs operator inside pipe first afterthat use finalize method. Ex.

    import { debounceTime } from 'rxjs/operators';

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.requestCount++;
        this.spinnerService.show();

     return next.handle(request)
            .pipe(
                debounceTime(1000),
                finalize(() => {
                    this.requestCount--;
                    if (this.requestCount === 0) {
                        this.spinnerService.hide();
                    }
                })
            );
Raj singh
  • 381
  • 1
  • 9
1

the answer: https://codeburst.io/rxjs-show-spinner-for-a-minimum-amount-of-time-807ac6b23227

Also, to achieve the opposite(not showing at all if a request is quick) take a look at race operator.

andriishupta
  • 497
  • 4
  • 8