2017-08-12 3 views
5

Ich habe versucht, einen HttpInterceptor zu erstellen, um einige Header für die Autorisierung zu jedem http hinzuzufügen, das passiert. Ich benötige die Header von einem Service namens AuthService. Hier ist der Code unter:Injector Error "Provider Parse Fehler: Kann keine zyklische Abhängigkeit instanziieren!"

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] 

ich die folgende Fehlermeldung:

Error: Provider parse errors: Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./[email protected]:-1

Ich habe bereits die vorherigen Antworten überprüft, aber ich verstehe nicht, wo die zyklische Abhängigkeit erkannt wurde. Was ich versuche zu tun, ist hier beschrieben: https://angular.io/guide/http#setting-new-headers

Antwort

7

Schauen Sie sich das GitHub Discussion (Issue #18224)

Als Abhilfe können Sie Injector manuell und injizieren entsprechenden Service innerhalb intercept Methode verwenden: 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:

Vor Angular 4.3.0 un zum Glück ist es unmöglich, Injector manuell innerhalb intercept Methode zu verwenden:

ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded

So gibt es eine weitere Abhilfe mit 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) 
     }) 
} 
+0

Sehr schöne und saubere Antwort, vielen Dank! :) – dave0688

2

Entfernen Sie AuthService aus Provider-Liste, wie es im Interceptor bereits so die zyklische Abhängigkeit importiert wird.

+2

AuthService in vielen Teilen meiner Anwendung verwendet wird, und ich brauche die gleiche Instanz überall. Irgendeine Option? – itsundefined

+0

Ich denke, ich habe das Problem behoben, aber es sieht blöd aus ... Ich habe den authService in zwei geteilt. In einer Datei habe ich alle Variablen und auf der anderen alle HTTP-Anfragen. Auf diese Weise benötige ich nur die Variablen auf meinem Interceptor, wodurch die zyklische Abhängigkeit eliminiert wird. Ist das ein Anti-Muster oder soll ich es behalten? Wie auch immer, danke für deine Zeit. – itsundefined

+0

@itsUndefined Wie haben Sie Ihre Serviceklasse in zwei geteilt? ist es wie zwei getrennte Klassen, die von der Basisdienstklasse abgeleitet sind? –

Verwandte Themen