我正在使用APP_INITIALIZER挂钩从本地json文件加载一些应用程序配置。加载配置后,我想在另一个提供程序中使用它(为生成的swagger-codegen服务设置BASE_PATH)。
我收到此错误:Uncaught TypeError: Cannot read property 'api' of undefined
我尝试访问AppInitService.settings.api
的值是AppInitService上的静态属性。我怀疑这是问题所在,但据我了解,APP_INITIALIZER挂钩应保证在继续之前先等待...
如何等待将值加载到APP_INITIALIZER中并准备好在其他提供者useValue
中重用?
app.module.ts
export function initializeApp(appConfig: AppInitService) {
return (): Promise<any> => appConfig.init()
}
@NgModule({
declarations: [...],
imports: [...],
providers: [
AppInitService,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [AppInitService],
multi: true,
},
{
provide: BASE_PATH,
useValue: AppInitService.settings.api,
},
],
app.config.service.ts
@Injectable()
export class AppInitService {
static settings: IAppConfig
private conf: IAppConfig
constructor(private http: HttpClient) {}
public getConf() {
return this.conf
}
init() {
const jsonFile = `assets/config/config.json`
return this.http
.get(jsonFile)
.pipe(
tap((returnedConfig: IAppConfig) => {
console.log('returnedConfig', returnedConfig)
AppInitService.settings = returnedConfig
this.conf = returnedConfig
})
)
.toPromise()
}
}
答案 0 :(得分:1)
您可以使用工厂提供程序。
{
provide: BASE_PATH,
useFactory: (service: AppInitService) => service.conf, // doesn't need to be static
deps: [AppInitService]
}
Angular只会在提供程序解析后第一次第一次调用工厂函数,但是您只是假设将在以后解析 。它可能暂时可以使用,但是以后可能会损坏甚至根本无法使用。
相反,使用可观察值作为可注入值。
@Injectable()
public class AppInitService {
public conf: ReplaySubject<any> = new ReplaySubject(1);
init() {
const jsonFile = `assets/config/config.json`
return this.http
.get(jsonFile)
.pipe(
tap((returnedConfig: IAppConfig) => this.conf.next(returnedConfig))
).toPromise()
}
}