I am using APP_INITIALIZER for fetching config from json and it works fine. Earlier i was having an auth guard as part of application and it used to work great.
Then we split the authorization logic into a library and it works fine if we call forRoot() or if we give static values to config but to allow dynamic configuration I used the InjectionToken from library to provide config without calling forRoot.
The code for app.module.ts is like this:
let authConfig: any; export function authConfigFactory() { return authConfig; } export function appInitializerFn(appConfigService: AppConfigService) { return () => { return appConfigService.loadAppConfig().then(() => { authConfig = { clientId: appConfigService.getConfig().CLIENT_ID, tokenEndpoint: appConfigService.getConfig().TOKEN_URL, redirectURL: "http://localhost", }; }); }; }; @NgModule({ ..... imports: [ .. AuthLib ], providers: [ AppConfigService, { provide: APP_INITIALIZER, useFactory: appInitializerFn, multi: true, deps: [AppConfigService] }, AuthLibService, { provide: 'authConfig', useFactory: authConfigFactory, deps: [] }, ..... ] bootstrap: [AppComponent] }) export class AppModule { } Now authConfigFactory is getting called way before appInitializerFn resulting in undefined and if i add async to authConfigFactory to prevent return statement till its defined then empty values are fed to AuthGuard resulting in invalid token url.
If i provide values manually in appInitializerFn before calling for promise the values gets translated and things work normally. But at that stage dynamic values are not present.
Code for app-config.service.ts:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { environment } from 'src/environments/environment'; import { AppConfig } from '../_models/app-config'; import { LoggingService } from './logging.service'; @Injectable() export class AppConfigService { static appConfig : AppConfig; private dataLoc: string; constructor(private http: HttpClient, private logger: LoggingService) { } loadAppConfig() { if(environment.production){ this.dataLoc = '/assets/data/appConfig.json'; } else{ this.dataLoc = '/assets/data/appConfig-dev.json'; } return new Promise<void>((resolve, reject) => { this.http.get(this.dataLoc).toPromise().then((response: AppConfig) => { AppConfigService.appConfig = <AppConfig>response; resolve(); }).catch((response: any) => { reject(`Could not load file '${this.dataLoc}': ${JSON.stringify(response)}`); }); }); } getConfig() { return AppConfigService.appConfig; } } Anything missing from library or code to make this work ?
I am bit new to Angular regime, let me know even in case i did some stupid mistake.
APP_INITIALIZERis correct. so the the cause of problem must be somewhere else. i suggest taking a look at the repo above and provide any further ideas to track the problem. i am suspectingAuthLibandAuthLibServicemight have something.