Reputation: 292
I have an angular 4 app that is broken down into different feature. So I have a shopping feature with all its components and billing feature with all its component.
However, I have an issue with configuration. I would like to share configuration between multiple feature of the app. My configuration is different for each feature so I created a base config class and inherit from it.
However in my app.module is did a registration such as below.
{ provide: BillingModuleConfig, useClass: ConfigService },
{ provide: ShoppingConfig, useClass: ConfigService }
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ShoppingConfig],
multi: true
}
However, this does not work for the BillingModuleConfig. Which implies when I inject BIllingConfig in the section I need it from I cannot get the config setting. Is there a reason why this would not work? My ConfigServiceFactory is the an external function that load the config file as below.
export function configServiceFactory(config: ConfigService) {
return () => config.load();
}
The config.load method loads all the configuration into a class that inherits from both ShoppingConfig and BillingConfig.
The config.load implementation is
import { Injectable, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { BillingModuleConfig} from '@razor/Billing';
import { ShoppingConfig } from '@razor/shopping';
import { environment } from './../../environments/environment';
import { HttpClient } from '@angular/common/http';
abstract class Settings implements BillingModuleConfig, ShoppingConfig {
public ShoppingAPIUrl: string;
public BillingApiUrl: string;
}
@Injectable()
export class ConfigService implements Settings {
constructor(private http: HttpClient) {}
public load() {
return new Promise((resolve, reject) => {
this.http
.get<Settings>(environment.configFileName)
.subscribe((config: AppSettings) => {
this.ShoppingAPIUrl= config.ShoppingAPIUrl;
this.BillingApiUrl= config.BillingApiUrl;
resolve(true);
});
});
}
}
Upvotes: 1
Views: 48
Reputation: 223054
Considering that config.load
assigns fetched configuration to ConfigService
class instance, it will work only for provider token that was specified as a dependency for APP_INITIALIZER
, which is ShoppingConfig
.
In order for the configuration to be fetched in BillingModuleConfig
, it should be specified, too:
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ShoppingConfig],
multi: true
},
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [BillingModuleConfig],
multi: true
}
However, this will result in two requests. To avoid this, the most simple way is to use ConfigService
everywhere. If BillingModuleConfig
and ShoppingConfig
were introduced because the configuration is currently combined but supposed to be divided later, they can reuse a common instance:
ConfigService,
{ provide: BillingModuleConfig, useExisting: ConfigService },
{ provide: ShoppingConfig, useExisting: ConfigService },
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ConfigService],
multi: true
}
Upvotes: 1