Skip to content

Instantly share code, notes, and snippets.

@muhammadawaisshaikh
Created March 20, 2021 10:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muhammadawaisshaikh/578b047ca6734dfcf9c63ce5f92bf7ae to your computer and use it in GitHub Desktop.
Save muhammadawaisshaikh/578b047ca6734dfcf9c63ce5f92bf7ae to your computer and use it in GitHub Desktop.
Implementing global loader Interceptor for Http Calls
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
...
// for token interceptor
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { LoaderInterceptorService } from './core/interceptors/loader-interceptor/loader-interceptor.service';
...
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: LoaderInterceptorService,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoaderService } from '../../services/loader/loader.service';
@Injectable({
providedIn: 'root'
})
export class LoaderInterceptorService 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' + err);
this.removeRequest(req);
observer.error(err);
},
() => {
this.removeRequest(req);
observer.complete();
});
// remove request from queue when cancelled
return () => {
this.removeRequest(req);
subscription.unsubscribe();
};
});
}
}
<div *ngIf="loading">
<img class="loading all-center" src={{loader}} />
<div class="loader-bg"></div>
</div>
@import '../../../styles.scss';
.loader-bg{
background: #ffffff;
opacity: 0.9;
position: fixed;
top: 0;
width: 100%;
height: 100%;
}
.loading {
position: absolute;
z-index: 1;
width: 100px;
height: auto;
}
import { Component, OnInit } from '@angular/core';
import { LoaderService } from '../../core/services/loader/loader.service';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.scss']
})
export class LoaderComponent implements OnInit {
loading: boolean;
loader: any = "../../../../assets/img/loading.gif";
constructor(
private loaderService: LoaderService
) { }
ngOnInit(): void {
this.loaderService.isLoading.subscribe((v) => {
console.log(v);
this.loading = v;
});
}
}
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LoaderService {
public isLoading = new BehaviorSubject(false);
constructor() { }
}
@lumberjack001
Copy link

lumberjack001 commented Mar 6, 2024

I'm geting this issue

ERROR NullInjectorError: R3InjectorError(AppModule)[LoaderInterceptor -> LoaderInterceptor -> LoaderInterceptor]:
NullInjectorError: No provider for LoaderInterceptor!

any Idea how to solve it?

@muhammadawaisshaikh
Copy link
Author

The error message "NullInjectorError: No provider for LoaderInterceptor" typically occurs when Angular cannot find a provider for a service or interceptor that is being used in your application. To resolve this issue, you need to make sure that the service or interceptor is properly provided in your Angular application.

Here are some steps you can take to solve this error:

Check AppModule: Ensure that the service or interceptor (LoaderInterceptor in this case) is properly provided in the providers array of your AppModule or the module where it is being used.

Import Interceptor: Make sure you have imported the LoaderInterceptor class and added it to the list of providers in the module where it is being used.

Check Module Imports: Verify that the module where LoaderInterceptor is provided is correctly imported into the module where it is being used.

Provider Registration: If LoaderInterceptor is a custom interceptor, ensure that it is registered as a provider either in the providers array of the module or using the HTTP_INTERCEPTORS multi-provider token.

Circular Dependency: Check for circular dependencies in your application, as they can sometimes cause issues with dependency injection.

NgModule Imports: Ensure that all necessary modules are imported into the imports array of your AppModule or the module where the interceptor is being used.

Angular Version: If you're using Angular version 9 or above, ensure that you're importing the interceptor correctly and that it is properly configured.

By following these steps and carefully reviewing your code, you should be able to identify and resolve the issue causing the "NullInjectorError: No provider for LoaderInterceptor" error in your Angular application.

@lumberjack001
Copy link

I think I've found the reason... the problem was with my use... so I'm trying to create a situation where, anytime the page loads or I make an Api call the loading variable is set to true and the loader shows

so on my app.component.ts I did this

import { Component, OnInit } from '@angular/core';
import { LoaderInterceptor } from './interceptors/loader/loader.interceptor';

@component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
loading: boolean | undefined;
constructor(private loaderInterceptor: LoaderInterceptor) {}

ngOnInit(): void {
this.loaderInterceptor.isLoading().subscribe(loading => {
this.loading = loading;
});
}
}

the constructor throws that error... so I removed it... I still have no idea how to achieve my aim

@muhammadawaisshaikh
Copy link
Author

muhammadawaisshaikh commented Mar 6, 2024 via email

@lumberjack001
Copy link

I'll be having a meeting in the next 6hours, can we make it 7hours?... it's currently 2:30 WAT(west African Time)... so 7hours would be 9:30pm... is that okay?

@lumberjack001
Copy link

Hello there, Good Day... I didn't any reply from you yesterday... Is it fine if we reschedule?

@muhammadawaisshaikh
Copy link
Author

muhammadawaisshaikh commented Mar 7, 2024 via email

@lumberjack001
Copy link

@muhammadawaisshaikh
Copy link
Author

muhammadawaisshaikh commented Mar 7, 2024 via email

@lumberjack001
Copy link

Oh yes I just received it... it's slated for 3pm tomorrow according to my time... I'd be at the office then, my schedules are usually tight during the day and freer at night... do nights work for you? Say between 8 and 9pm?

@muhammadawaisshaikh
Copy link
Author

muhammadawaisshaikh commented Mar 8, 2024 via email

@lumberjack001
Copy link

I think that would be 12am... Pakistan time

@lumberjack001
Copy link

I would be available all day tomorrow (saturday)... Maybe that would work best?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment