angularloaderhttpbackend

ng-http-loader not working for API calls handled via httpbackend


I was trying to create a service so that all API calls in that service will not be appended with token. I achieved this using HttpBackend. But now the ng-http-loader is not working for these API's.

What I Require

ng-http-loader to work in API calls handled through HttpBackend.

home-http.service.ts

@Injectable()
export class HomeHttpService {
  private http: HttpClient;
  constructor(handler: HttpBackend) {
    this.http = new HttpClient(handler);
  }

app.module.ts

    @NgModule({
      declarations: [AppComponent],
      imports: [
        BrowserModule,
        TooltipModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        HttpClientModule,
        NgbModule,
        AuthModule,
        AppRoutingModule,
        ToastrModule.forRoot(),
        NgHttpLoaderModule.forRoot()
      ],
      providers: [
        { provide: ErrorHandler, useClass: ErrorsHandler },
        { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
      ],
      bootstrap: [AppComponent]
    })

app.component.html

 <router-outlet></router-outlet>
 <ng-http-loader [backdrop]="true" [debounceDelay]="100" [extraDuration]="300" [minDuration]="300" [opacity]="0.6" [backgroundColor]="'#767676'" [spinner]="spinkit"></ng-http-loader>

api.service.ts

import { HomeHttpService } from '../home-http.service';
import { Observable } from 'rxjs';
import { environment } from 'environments/environment';

@Injectable()
export class APIService {
  constructor(private apiservice: HomeHttpService) {}

The ng-http-loader is working in api calls from all other services except the api.service.ts


Solution

  • After discussing this, here are the key points.

    When you provide HttpBackend in HttpClient, it will ignore the all the interceptors, and hence ng-http-loader will not work, as it is unaware of the request.

    Now this can be overcome by using header with the request as mentioned here.

    Interceptor

    export const InterceptorSkipHeader = 'X-Skip-Interceptor';
    
    @Injectable()
    export class SkippableInterceptor implements HttpInterceptor {
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (req.headers.has(InterceptorSkipHeader)) {
          const headers = req.headers.delete(InterceptorSkipHeader);
          return next.handle(req.clone({ headers }));
        }
        ...  // intercept
      }
    }
    

    Now, from service, for the API you wish not to have interceptor, you can set this header.

    const headers = new HttpHeaders().set(InterceptorSkipHeader, '');
    this.httpClient.get(someUrl, { headers })
        ...