How to Show spinner for every HTTP requests in angular 5?

This has nothing to do with HttpClient or HTTP Requests. It is a question of how to handle asynchronous calls in general (HTTP or not).

You should have

<div class="spinner" *ngIf="loading"; else showWhenLoaded"><div>
<ng-template #showWhenLoaded>
    <div>Your Content</div>
</ng-template>

and in the ts-file:

loading: boolean = true;

methodToTriggerRequest() {
    this.loading = true;
    this.http.get(...).subscribe(response => {
        if (resposnseNotAnError(response)) {this.loading = false}
    })
}

You can use Angular HttpInterceptor to show a spinner for all your requests, Here's a good medium article on how to implement an http interceptor

Also, you will have to create a spinner service/module and inject it in your http interceptor. Finally, in your intercept method you can use the finally rxJs method to stop your spinner. Here's a simple implementation:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.spinnerService.start();
    return next.handle(req).finally(res => this.spinnerService.stop() );
}

Enjoy!

Bonus: Here's a spinner service implementation example


Source Link

Create a service

//loader.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoaderService {

  public isLoading = new BehaviorSubject(false);
  constructor() { }
}

Create Loader Interceptor

    // loader.interceptors.ts
    import { Injectable } from '@angular/core';
    import {
        HttpErrorResponse,
        HttpResponse,
        HttpRequest,
        HttpHandler,
        HttpEvent,
        HttpInterceptor
    } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { LoaderService } from './loader.service';

    @Injectable()
    export class LoaderInterceptor implements HttpInterceptor {
        private requests: HttpRequest<any>[] = [];

        constructor(private loaderService: LoaderService) { }

        removeRequest(req: HttpRequest<any>) {
            const i = this.requests.indexOf(req);
            if (i >= 0) {
                this.requests.splice(i, 1);
            }
            this.loaderService.isLoading.next(this.requests.length > 0);
        }

        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

            this.requests.push(req);
            console.log("No of requests--->" + this.requests.length);
            this.loaderService.isLoading.next(true);
            return Observable.create(observer => {
                const subscription = next.handle(req)
                    .subscribe(
                        event => {
                            if (event instanceof HttpResponse) {
                                this.removeRequest(req);
                                observer.next(event);
                            }
                        },
                        err => {
                            alert('error returned');
                            this.removeRequest(req);
                            observer.error(err);
                        },
                        () => {
                            this.removeRequest(req);
                            observer.complete();
                        });
                // remove request from queue when cancelled
                return () => {
                    this.removeRequest(req);
                    subscription.unsubscribe();
                };
            });
        }
    }

Now create a loader component then add in the app component

  //loader.interceptor.ts
  import { Component, OnInit } from '@angular/core';
  import { LoaderService } from '../loader.service';

  @Component({
    selector: 'app-loading',
    templateUrl: './loading.component.html',
    styleUrls: ['./loading.component.css']
  })
  export class LoaderComponent implements OnInit {

    loading: boolean;
    constructor(private loaderService: LoaderService) {
      this.loaderService.isLoading.subscribe((v) => {
        console.log(v);
        this.loading = v;
      });
    }
    ngOnInit() {
    }

  }

The complete guide is here with a material mat-progress-spinner usage. Very cool!