Angular HTTP Interceptor - Display spinner in multi-module app

angular 8 loading spinner on http request
angular http progress
angular loading spinner observable
angular httpclient progress bar
http interceptor angular 7 example
http interceptor angular 5 loading
angular http interceptor for specific url
angular loading screen

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:

My Angular 5 app has multiple multiple modules. The HTTP interceptor is in the "services" module.

I think I'm having a dependency injection problem because the code HTTP interceptor code doesn't get executed when I debug my code with Chrome Dev Tools.

api-interceptor.ts

import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch'
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import {
    HttpEvent,
    HttpInterceptor,
    HttpHandler,
    HttpRequest,
    HttpResponse
} from '@angular/common/http';
import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';

@Injectable()
export class ApiInterceptor implements HttpInterceptor {

    private count: number = 0;

    constructor(private spinner: Ng4LoadingSpinnerService) { }

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

        if (this.count == 1) this.spinner.show();

        let handleObs: Observable<HttpEvent<any>> = next.handle(req);

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

        return handleObs;
    }

}

api.service.ts

import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import { TokenService } from './token.service';

@Injectable()
export class ApiService {

    constructor(
        private http: Http,
        private session: TokenService,
        @Inject('BASE_URL') private baseUrl) { }

    get(entityRoute: string): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.get(apiRoute, options);
    }

    post<T>(entityRoute: string, entity: T): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.post(apiRoute, entity, options);
    }

    put<T>(entityRoute: string, entity: T): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.post(apiRoute, entity, options);
    }

    private getApiRoute(entityRoute: string): string {
        return `${this.baseUrl}api/${entityRoute}`;
    }

    private generateRequestOptions(): RequestOptions {
        let headersObj = null;
        let accessToken = this.session.getAccessToken();

        if (accessToken) {
            headersObj = {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + accessToken
            };
        } else {
            headersObj = {
                'Content-Type': 'application/json'
            };
        }

        let headers = new Headers(headersObj);
        return new RequestOptions({ headers: headers });
    }

}

services.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';

import {
    ApiInterceptor,
    ApiService,
    TokenService
} from './index';

@NgModule({
    imports: [
        CommonModule,
        HttpModule,
        Ng4LoadingSpinnerModule
    ],
    providers: [
        ApiInterceptor,
        ApiService,
        TokenService
    ]
})
export class ServicesModule { }

export * from './index';

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';

import { BootstrapModule } from './bootstrap/bootstrap.module';
import { ServicesModule, ApiInterceptor } from './services/services.module';
import { AppComponent } from './app-component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [
        BrowserModule,
        Ng4LoadingSpinnerModule.forRoot(),
        BootstrapModule,
        ServicesModule
    ],
    providers: [
        {
            provide: 'BASE_URL',
            useFactory: getBaseUrl
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: ApiInterceptor,
            multi: true,
        }
    ]
})
export class AppModule {
}

export function getBaseUrl(): string {
    return document.getElementsByTagName('base')[0].href;
}

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.

angular5 - Angular HTTP Interceptor, 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  Our goal is to apply a spinner on top of any component that relies on an HTTP request. First we need to create a simple component that has it can take the size of its parent and has a spinner in the middle. I am using the Angular Material library to make things simpler. This component is using a single service called HttpStateService.


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;
    }

Angular HTTP Interceptor - Display spinner in multi - html, Angular4: Using HttpClient's interceptor to setup a spinner My Angular 5 app has multiple multiple modules. The HTTP interceptor is in the "services" module. Create an HTTP Interceptor to detect when a request has started/ended. Create a shared Angular service to inform the components about the status of the request. Use the service in components to show and hide angular material spinner in the user interface. Demonstration of Angular Material spinner component:


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!

Angular Spinner and Http Interceptor - Arunkumar V, It is best practice to show a spinner on the front end during http requests. work on a dashboard where various components and services makes multiple http requests together. I used <ngx-spinner> in my app.component.html. Do not forget to add our interceptor and the spinner in angular.modules.ts. Display a loader on every HTTP request using Interceptor in Angular 7 Posted by Viktor Borisov As you may already know, as of version 4.3, Angular introduced a new HttpClient.


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

Display a loader on every HTTP request using Interceptor in Angular , Tagged with angular, http, component, interceptor. Our goal is to apply a spinner on top of any component that relies on an HTTP request that you might try to do through the HttpClientModule and manipulate them or react that we don't want the application to act * automatically * * The interceptor also  HTTP Guide. Descriptionlink. Most interceptors transform the outgoing request before passing it to the next interceptor in the chain, by calling next.handle(transformedReq). An interceptor may transform the response event stream as well, by applying additional RxJS operators on the stream returned by next.handle().


Angular: display a spinner on any component that does an HTTP , 7) Update App Module with HttpClientModule , Interceptor and Loader service. Let's get started! #1 Update Angular CLI tool. Angular Interceptors  Angular 9|8|7 | Show Global Spinner/ Loader on HTTP calls in few steps using Angular Interceptors in Angular 4.3+ Last updated on April 24, 2020 Jolly.exe In this post, we will learn how to use Angular’s Interceptor class to show a common loader/ spinner indicating about an API Http call is in progress.


Angular 9|8|7, Implement an abstract solution to show an Angular Material spinner an HTTP request is taking place using a custom HTTP interceptor and a the app.module.​ts so that Angular knows how to intercept requests. multi: true. Since I couldn’t find any resources on Angular 5 app structure with multiple modules, I decided that whilst rebuilding an AngularJS app, I would implement a multiple-module architecture and document it. Below is the approach I took, with some justifications for the decisions I took. In the near future I plan to write more posts


Angular Material Display Spinner with Every HTTP Request , Hi there, I don't know how to use it with interceptor. Spinner never appears. app.​module.ts import { NgxSpinnerModule } from 'ngx-spinner'; imports: [ . HTTP Loading Spinner Interceptor Module for AngularJS - jarnix/angular-httpLoadingInterceptor