Configure a external Angular lib with .forRoot() that depends on a main Application service for populate config values

1.3k views Asked by At

I have a custom Library that needs custom configuration within the forRoot() Library module, but I need to use an App Config Module that loads that configuration asynchronously instead of using static injected data as following.

// Custom Library module

@NgModule({})
export class FormatModule {
    constructor() {}

    public static forRoot(config: FormatConfig) {
        // Do something with the config
    }
}

where FormatConfig is the following:

export interface FormatConfig {
    [key: string]: any
} 

Usage of that module within the main AppModule:

export function loadConfig(configService): Observable<FormatConfig> {
    return configService.extractFormatConfig();
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    FormatModule.forRoot(),
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

I also have an Injection Token to assign the config data:

export const FORMAT_CONFIG = new InjectionToken<string>('FORMAT_CONFIG');

Is possible to use the forRoot method and a factory to populate the data which the module needs. I won’t inject the ConfigService inside the FormatModule, because that would make the FormatModule dependant of another external service.

1

There are 1 answers

1
icekson On

define injection token

export const FORMAT_CONFIG: InjectionToken<FormatConfig> = new InjectionToken<FormatConfig>('FORMAT_CONFIG');

use your factory when declaring the AppModule

export function loadConfig(configService: ConfigService): Observable<FormatConfig> {
    return configService.extractFormatConfig();
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    FormatModule.forRoot(),
    BrowserModule,
  ],
  providers: [{
    provide: FORMAT_CONFIG,
    useFactory: loadConfig,
    deps: [ConfigService]
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }

now you can inject your config inside your FormatModule like the following

...

constructor(@Inject(FORMAT_CONFIG) private formatConfig: FormatConfig)