Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - HTTP Interceptor And Configuration loaded on APP_INITIALIZE

I have a configuration module with a factory that executes when the application is initialized (APP_INITIALIZER)

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

Everything works ok if i print the data on a page/component.

The problem is when i try to use the configuration in a Service that gets called from an HttpInterceptor:

    {
        provide: HTTP_INTERCEPTORS,
        useClass: TokenInterceptor,
        multi: true
    },

Interceptor:

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

AuthenticationService:

export class AuthenticationService implements AuthService {
    API_URL = this.configService.tokenServer;
....

The problem is that configService is Undefined.

Is there any way to postpone an interceptors initilization until APP_INITIALIZER is finished?

My goal is to have a unique build for all environments.


After trying different alternatives:

I couldn't find a good, maintainable and neat solution for the problem.

like image 439
Sergio Daniel Coronel Malvarez Avatar asked Oct 30 '18 14:10

Sergio Daniel Coronel Malvarez


1 Answers

Is there any way to postpone an interceptors initilization until APP_INITIALIZER is finished?

see How to make an angular module to ignore http interceptor added in a core module

I personally used deg answer, in which simply use HttpBackend dependency instead of HttpClient in APP_INITIALIZE, because I used to retrieve Configuration via http call. Http Call rised up Interceptor which basically needed Configuration, ending up in a circular dependency. (HttpBackend doesn't wakeup Interceptors)

export class AuthenticationService implements AuthService { API_URL = this.configService.tokenServer; ....

In your case it seems that you are also missing dependency. Some code is missing, but in AuthenticationService Module you probably should declare dependency, like:

{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, deps: [AuthenticationService ], multi: true },

and variable initialization should depend on Service constructor:

export class AuthenticationService implements AuthService {
    API_URL = this.configService.tokenServer;
....

should be:

export class AuthenticationService implements AuthService {
    constructor(configService: ConfigService) {
       this.API_URL = configService.tokenServer;
    }

hope it helps even if reaally late

like image 79
RiccardoBucchi Avatar answered Oct 11 '22 00:10

RiccardoBucchi