注入服务时出现Angular 5 Http拦截器错误 [英] Angular 5 Http Interceptors error when injecting service

查看:191
本文介绍了注入服务时出现Angular 5 Http拦截器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在angular 5+中使用自定义HttpInterceptors时,我收到以下奇怪的依赖项注入行为.

I am receiving the following strange dependency injection behavior when using custom HttpInterceptors in angular 5+.

以下简化的代码可以正常工作:

The following simplified code works fine:

    export class AuthInterceptor implements HttpInterceptor {
        constructor(private auth: AuthService) {}

        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const token = this.auth.getToken();
            return next.handle(req);
        }
    }
    export class AuthService {
        token: string;
        constructor() {
          console.log('AuthService.constructor');
        }
    }

但是......

AuthService自身具有1个或多个依赖项时

When the AuthService has 1 or more dependencies on its own e.g.

   export class AuthService {
      token: string;
      constructor(private api: APIService) {
         console.log('AuthService.constructor');
      }
   }

angular试图重复创建AuthService的新实例,直到出现以下错误:

angular is trying to repeatedly create new instances of AuthService until I receive the following errors:

日志显示AuthService.constructor消息约400次

The log is displaying the AuthService.constructor message ~400 times

Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule

Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule

app.component.html:44错误RangeError:最大调用堆栈大小 超过

app.component.html:44 ERROR RangeError: Maximum call stack size exceeded

然后我尝试使用Injector类注入服务-

I then tried injecting the service using the Injector class -

 export class AuthService {
      token: string;
      api: APIService;
      constructor(private injector: Injector) {
         this.api = this.injector.get(APIService);
         console.log('AuthService.constructor');
      }
   }

但出现相同的错误(最大调用堆栈大小).

but getting the same error (maximum call stack size).

APIService是一个简单的服务,仅将HttpClient注入其构造函数中.

The APIService is a simple service that only injects the HttpClient in its constructor.

@Injectable()
export class APIService {
    constructor(private http: HttpClient) {}
}

最后,当我使用InjectorAuthService注入到Interceptor中时,错误消失了,但是AuthService被实例化了200多次:

Lastly, when I inject the AuthService into the Interceptor using the Injector, the error disappears but the AuthService is being instantiated 200+ times:

export class AuthInterceptor implements HttpInterceptor {
    auth: AuthService;
    constructor(private injector: Injector) {}
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
           this.auth = this.auth || this.injector.get(AuthService);
           const token = this.auth.getToken();
           return next.handle(req);
        }
    }

查看官方文档和其他示例,从技术上来说,将服务注入Http拦截器似乎是可行的.是否有任何限制或其他可能缺少的设置?

Looking at the official documentation and other example it seems as it is technically possible to inject services into the Http Interceptors. Is there any limitation or any other setup that might be missing?

推荐答案

因此,事实证明,如果您注入到Http Interceptor中的服务具有对HttpClient的依赖关系,则会导致循环依赖关系.

So it turns out that if the service you inject into the Http Interceptor has a dependency on HttpClient, this leads to a cyclic dependency.

由于我的AuthService是所有不同逻辑的混合(登录/注销,路由用户,保存/加载令牌,进行api调用),因此我将拦截器所需的部分分为了自己的服务(仅用户)凭据和令牌),然后将其成功注入到拦截器中.

Since my AuthService was a mix of all different logics (login/out, routing the user, saving/loading tokens, making api calls), I separated the part needed for the interceptors into its own service (just the user credentials & tokens) and now injecting it successfully into the Interceptor.

export class AuthInterceptor implements HttpInterceptor {
    constructor(private credentials: CredentialsService) {}
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const token = this.credentials.getToken();
        const api_key = this.credentials.getApiKey();
    }
}

export class CredentialsService {
    token: string;
    user: IUser;
    constructor(private http: HttpClient) {
        this.loadCredentialsFromStorage();
    }
}

这似乎工作正常.希望这对某人有帮助.

This seems to work fine. Hope this helps someone.

这篇关于注入服务时出现Angular 5 Http拦截器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆