I've been inspired by this answer in order to provide my APP_Config as an injection token, I got this in my main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { APP_CONFIG } from './app/config/AppConfig';
function configListener(this: any) {
try {
const configuration = JSON.parse(this.responseText);
// pass config to bootstrap process using an injection token
platformBrowserDynamic([
{ provide: APP_CONFIG, useValue: configuration }
])
.bootstrapModule(AppModule)
.catch(err => console.error(err));
} catch (error) {
console.error(error);
}
}
function configFailed() {
console.error('Error: retrieving config.json');
}
const request = new XMLHttpRequest();
request.addEventListener('load', configListener);
request.addEventListener('error', configFailed);
request.open('GET', './assets/app.config.json');
request.send();
export interface AppConfig {
clientId: string;
clientSecret: string;
...
}
I can use the loaded config from any service in my application
constructor(@Inject(APP_CONFIG) private appConfig: AppConfig) {}
But I'm not able to pass the config for the shared Library in my app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
...,
LibModule.forRoot({
authConfig: {
clientId: 'XXXXXXXX',
dummyClientSecret: 'XXXXXX',
...
}
})
],
providers: [
],
bootstrap: [AppComponent],
})
export class AppModule {}
How can I provide the config in forRoot()
from the APP_CONFIG InjectionToken ? is there a relevant solution or I have to update the shared Library module ?
@NgModule({
declarations: [],
imports: [...],
providers: [...],
})
export class LibModule {
static forRoot(configuration: Config): ModuleWithProviders<LibModule> {
return {
ngModule: LibModule,
providers: [{ provide: AUTH_CONFIGURATION, useValue: configuration }],
};
}
}
export const AUTH_CONFIGURATION = new InjectionToken<Config>('AUTH_CONFIGURATION');
PS: I am trying to load my app configuration at the runtime which allows to reuse the same build artifact for all environments (I got ideas from this article)
My issue is already mentioned here https://github.com/angular/angular/issues/23279#issuecomment-412108311
The solution may be quite simple ! we can provide the AUTH_CONFIGURATION directly from our application as the following
const generateAuthConfiguration = (appConfig: AppConfig) => {
return {
authConfig: {
clientId: appConfig.clientId,
dummyClientSecret: appConfig.clientSecret,
}
}
}
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
...,
{
ngModule: LibModule,
providers: [
{
provide: AUTH_CONFIGURATION,
useFactory: generateAuthConfiguration,
deps: [APP_CONFIG]
}
]
}
],
providers: [
],
bootstrap: [AppComponent],
})
export class AppModule {}
That's it !