I tried to create an HttpInterceptor to add some headers for authorization to every http that happens. I need to get the headers from a service called AuthService. Here is the code below:
Interceptor:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { AuthService } from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) { }
}
AuthService:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable()
export class AuthService {
constructor(private http: HttpClient) { }
}
AppModule:
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
}, AuthService]
I receive the following error:
Error: Provider parse errors: Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
I already checked the previous answers but I don't understand where the cyclic dependency was detected. What I am trying to do is described here: https://angular.io/guide/http#setting-new-headers
Look at this GitHub Discussion (Issue #18224)
As a workaround you can use Injector
manually and inject relevant service inside intercept
method: https://github.com/angular/angular/issues/18224#issuecomment-316957213
I resolved simply not setting authService in constructor but getting in the intercept function.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // Get the auth header from the service. const auth = this.inj.get(AuthenticationService); const authToken = auth.getAuthorizationToken(); ... }
UPDATE:
Prior to Angular 4.3.0
unfortunately it's impossible to use Injector
manually inside intercept
method:
ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded
So there is one more workaround using rxjs
:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return Observable.create((observer: any) => {
setTimeout(() => {
const authService = this.injector.get(AuthenticationService)
observer.next(authService.getAuthorizationHeader())
observer.complete()
})
})
.mergeMap((Authorization: string) => {
let authReq = req
if (Authorization) {
authReq = req.clone({
setHeaders: {
Authorization
}
})
}
return next.handle(authReq)
})
}
Remove AuthService from providers list as it is imported in the Interceptor already thus the cyclic dependency.
Remove following from AuthService -
import { HttpClient } from '@angular/common/http';
The reason is - HttpClient using interceptor internally and interceptor using AuthService and AuthService is using HttpClient. thus it gives "cyclic dependency" error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With