Reputation: 2465
I am working on an Angular 7 Application with es6 Javascript version and Swagger.
I am trying to add the config to APP_INITIALIZER in the app.module:
export class SettingsProvider {
private config: AppConfig;
constructor(private httpClient: HttpClient) {}
public loadConfig(): Promise<any> {
return this.httpClient.get(`assets/configs/config.json`).pipe(
map(res => res as AppConfig))
.toPromise()
.then(settings => {
this.config = settings;
});
}
public get configuration(): AppConfig {
return this.config;
}
}
in the app.module:
{ provide: APP_INITIALIZER, useFactory: init, deps: [SettingsProvider], multi: true },
{ provide: API_BASE_URL, useFactory: baseApiUrlSetting, deps: [SettingsProvider], multi: true },
export function init(settingsProvider: SettingsProvider) {
return () => settingsProvider.loadConfig();
}
export function baseApiUrlSetting(settingsProvider: SettingsProvider) {
return settingsProvider.configuration.baseApiUrl;
}
Everything works perfectly until I inject the API_BASE_URL token. The compiler is probably not finished with loading the configs so, the value of settingsProvider is always null.
Cannot read property 'baseApiUrl' of undefined
Does anybody know a possible solution for that? Thanks!
Upvotes: 3
Views: 1710
Reputation: 48
I had the same problem and ended up with this solution:
main.ts
AppConfigService.loadConfig().then(() => {
return platformBrowserDynamic().bootstrapModule(AppModule);
})
app-config-service.ts
import { Injectable } from '@angular/core';
import { AppConfig } from './app-config.models';
@Injectable({ providedIn: 'root' })
export class AppConfigService<T extends AppConfig = AppConfig> {
static appConfig: AppConfig;
constructor() { }
static loadConfig(): Promise<void> {
return new Promise((resolve, reject) => {
const oReq = new XMLHttpRequest();
oReq.addEventListener('load', (resp) => {
if (oReq.status === 200) {
try {
AppConfigService.appConfig = JSON.parse(oReq.responseText);
} catch (e) {
reject(e);
}
resolve();
} else {
reject(oReq.statusText);
}
});
oReq.open('GET', '/assets/configs/config.json');
oReq.send();
});
}
getConfig(): T {
return AppConfigService.appConfig as T;
}
}
app-config.models.ts
export interface AppConfig {
ApiBaseUrl: string;
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { API_BASE_URL } from './nswag-client.service';
import { AppConfigService } from '../app-config-service';
export function getApiBaseUrl(): string {
return AppConfigService.appConfig.ApiBaseUrl;
}
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
...
],
providers:
[
{
provide: API_BASE_URL,
useFactory: getApiBaseUrl
},
...
],
bootstrap: [AppComponent]
})
export class AppModule { }
Cred to michael-lang https://github.com/ngrx/platform/issues/931
Upvotes: 1