Angular - HTTP 拦截器和配置加载到 APP_INITIALIZE

Ser*_*rez 9 configuration angular-http-interceptors angular angular-lifecycle-hooks

我有一个带有工厂的配置模块,在应用程序初始化时执行(APP_INITIALIZER)

export function ConfigFactory(config: ConfigService) {
    const res = () => config.load();
    return res;
}
...
{
     provide: APP_INITIALIZER,
     useFactory: ConfigFactory,
     deps: [ConfigService],
     multi: true
}
Run Code Online (Sandbox Code Playgroud)

如果我在页面/组件上打印数据,一切正常。

问题是当我尝试在从 HttpInterceptor 调用的服务中使用配置时:

    {
        provide: HTTP_INTERCEPTORS,
        useClass: TokenInterceptor,
        multi: true
    },
Run Code Online (Sandbox Code Playgroud)

拦截器:

constructor(private authenticationService: AuthenticationService) {}
  intercept(request: HttpRequest<any> , next: HttpHandler): Observable<HttpEvent<any>> {

    this.authenticationService.getAccessToken().subscribe((token: string) => { this.accessToken = token.toString(); });
      this.authenticationService.getCurrentUser().subscribe((currentU: string) => { this.currentUser = currentU.toString(); });
    if (this.accessToken)  {
        request = request.clone({
        setHeaders: {
            Authorization: `Bearer ${this.accessToken}`,
            actor: this.currentUser,
    //      modulo: 'AltaActivoFijo'
        }
        });
    }
    return next.handle(request);
  }
Run Code Online (Sandbox Code Playgroud)

身份验证服务:

export class AuthenticationService implements AuthService {
    API_URL = this.configService.tokenServer;
....
Run Code Online (Sandbox Code Playgroud)

问题是 configService 是未定义的。

有没有办法推迟拦截器初始化,直到 APP_INITIALIZER 完成?

我的目标是为所有环境构建一个独特的版本。


尝试不同的选择后:

我无法为这个问题找到一个好的、可维护的和整洁的解决方案。

小智 6

有没有办法推迟拦截器初始化,直到 APP_INITIALIZER 完成?

请参阅如何制作角度模块以忽略核心模块中添加的 http 拦截器

我个人使用了 deg 答案,其中在 APP_INITIALIZE 中简单地使用 HttpBackend 依赖项而不是 HttpClient,因为我曾经通过 http 调用检索配置。Http Call 升起 Interceptor 基本上需要配置,最终陷入循环依赖。(HttpBackend 不会唤醒拦截器)

导出类 AuthenticationService 实现 AuthService { API_URL = this.configService.tokenServer; ....

在您的情况下,您似乎也缺少依赖项。缺少一些代码,但在 AuthenticationService 模块中,您可能应该声明依赖项,例如:

{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, deps: [AuthenticationService ], multi: true },
Run Code Online (Sandbox Code Playgroud)

和变量初始化应该依赖于服务构造函数:

export class AuthenticationService implements AuthService {
    API_URL = this.configService.tokenServer;
....
Run Code Online (Sandbox Code Playgroud)

应该:

export class AuthenticationService implements AuthService {
    constructor(configService: ConfigService) {
       this.API_URL = configService.tokenServer;
    }
Run Code Online (Sandbox Code Playgroud)

希望它有帮助,即使真的很晚