'How to fix no provider for localStorage and circular dependency
I have an angular frontend project generated with nrwl nx. After implementing an interceptor I am getting the following two errors after trying to make a request:
The first call causes this one:
ERROR NullInjectorError: R3InjectorError(AppModule)[InjectionToken HTTP_INTERCEPTORS -> [object Object] -> LocalStorageService -> LocalStorageService -> LocalStorageService]:
NullInjectorError: No provider for LocalStorageService!
THe second call of the same request right after the first one causes this one:
ERROR Error: NG0200: Circular dependency in DI detected for InjectionToken HTTP_INTERCEPTORS. Find more at
The funny thing is I have provided my interceptor in my app.module, I thought this was enough and the second error confuses me greatly as I did not import or use the interceptor directly. I hope someone here can help me out:
App-module:
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
NbLayoutModule,
LoginComponentModule,
DashboardModule,
AppRoutingModule,
NbThemeModule.forRoot({name: 'default'}),
NbLayoutModule,
NbEvaIconsModule,
MatToolbarModule,
MatIconModule,
MatButtonModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
}
],
bootstrap: [AppComponent],
})
export class AppModule {}
interceptor:
@Injectable({providedIn: "root"})
export class AuthInterceptor implements HttpInterceptor {
constructor(private localStorage: LocalStorageService, private sessionStorage: SessionStorageService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!request.url || (request.url.startsWith('http') && !(environment.rootUrl && request.url.startsWith(environment.rootUrl)))) {
return next.handle(request);
}
const token =
this.localStorage.retrieve('token') ||
this.sessionStorage.retrieve('token');
if (token) {
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + token,
},
});
}
return next.handle(request);
}
}
Authentication service:
export class AuthenticationService{
isAuthenticated = false;
constructor(
private handler: HttpBackend,
private http: HttpClient,
private router: Router,
) {
}
authenticateUser(login: LoginModel){
this.http = new HttpClient(this.handler)
return this.http.post(environment.rootUrl + 'api/authenticate', {
username: login.username,
password: login.password,
}).subscribe({
next: (data) => {
localStorage.setItem('token', JSON.stringify(data))
this.router.navigate(['/dashboard'])
}, error: (error) => {
this.isAuthenticated = false
}
})
}
isUserLoggedIn(){
return !!localStorage.getItem('token')
}
and material service which makes a request:
@Injectable({
providedIn: 'root'
})
export class MaterialService {
constructor(private httpRequest: HttpClient) { }
getMaterials() {
return this.httpRequest.get("/api/product/api/materials")
}
}
I have other modules but as far as I understand if I provided it in the app-module it should be enough, at least I thought so. I hope you guys can help me out
EDIT added the codes where authentication service is used:
export class AuthGuard implements CanActivate {
constructor(
private auth: AuthenticationService,
private router: Router
) {
}
canActivate(): Promise<boolean> {
return new Promise(resolve => {
if (this.auth.isUserLoggedIn()) {
resolve(true)
} else {
this.router.navigate(['authenticate'])
resolve(false)
}
})
}
}
login.component:
export class LoginComponent {
status = 'basic'
userNameErrorText= 'Username is required'
passwordErrorText= 'Password is required'
constructor(
private authService: AuthenticationService
) { }
loginForm = new FormGroup({
userNameInput: new FormControl('', [Validators.required]),
passwordInput: new FormControl('', [Validators.required])
})
public hasError = (controlName: string, errorName: string) =>{
return this.loginForm.controls[controlName].hasError(errorName);
}
login(){
if(this.loginForm.valid){
this.authService.authenticateUser({
username: this.loginForm.controls['userNameInput'].value,
password: this.loginForm.controls['passwordInput'].value
})
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
