Injector Error" Provider parse errors:无法实例化循环依赖!"

时间:2017-08-12 19:53:55

标签: angular

我尝试创建 HttpInterceptor ,为每个发生的http添加一些授权标头。我需要从名为 AuthService 的服务中获取标头。以下是代码:

拦截器:

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]

我收到以下错误:

  

错误:提供程序解析错误:       无法实例化循环依赖! InjectionToken_HTTP_INTERCEPTORS(" [ERROR - >]"):在NgModule AppModule中   在./AppModule@-1:-1

我已经检查过以前的答案,但我不明白检测到循环依赖的位置。我想要做的是在这里描述:https://angular.io/guide/http#setting-new-headers

3 个答案:

答案 0 :(得分:19)

看看这个GitHub Discussion (Issue #18224)

作为一种解决方法,您可以手动使用Injector并在intercept方法中注入相关服务:https://github.com/angular/angular/issues/18224#issuecomment-316957213

  

我决定不在构造函数中设置authService而是获取   在拦截功能中。

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();
    ...
}

更新:

在Angular 4.3.0之前,遗憾的是,Injector方法无法手动使用intercept

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

因此,使用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)
        })
}

答案 1 :(得分:4)

从提供者列表中删除AuthService,因为它已经在Interceptor中导入,因此已经是循环依赖。

答案 2 :(得分:2)

从AuthService中删除关注者-

import { HttpClient } from '@angular/common/http';

原因是-内部使用拦截器的HttpClient以及使用AuthService的拦截器和AuthService使用HttpClient。因此会产生“循环依赖”错误。