Background: I need to perform couple of initial checks during the application start up (1) read angular app config from ./assets/conf
I don't think you actually need an initializer in your case. You just have a value that other services depend on. The problem in your code is that you have an async value and try to expose it as a sync value.
I think your problems would be solved if you would just expose the config as an Observable and "await" it where it's needed. The benefits are that the application loads as much as it can until the config requests are done.
For example the shareReplay(1)
operator will keep in memory the item and will defer the HTTP request until it's actually needed:
export class ConfigService {
configData$ = this.httpClient.get<{config1:string}>('./assets/config.json').pipe(shareReplay(1));
constructor(private httpClient: HttpClient) { }
}
Now your 2nd service can await the configData from the 1st service. Or just transform it via observable piping and expose it further as an observable to defer everything until it's actually needed.
@Injectable({
providedIn: 'root'
})
export class SettingsService {
settingsData$ = this.configService.configData$.pipe(
map(c => c.config1 + '...and config service dependent action'),
shareReplay(1), // also keep the value in memory maybe?
);
constructor(
private httpClient: HttpClient,
private configService: ConfigService
) { }
}
export class HelloComponent implements OnInit {
@Input() name: string;
dataFromConfigSvc: Observable<string>;
constructor(private configService: ConfigService) { }
ngOnInit() {
// you could either use async pipe in the template or subscribe here and get the value
this.dataFromConfigSvc = this.configService.configData$.pipe(map(c => c.config1));
}
}
just use
useFactory: (appConfigSvc: ConfigService,settingsService:SettingsService) => {
return () => {
return appConfigSvc.loadConfig().then(()=>{
return settingsService.loadConfig()
});
};
}
See your forked code in stackblitz