Reputation: 3722
Before bootstraping my angular app I need to perform an async operation which returns some context for the application. Before starting, I need to init some 3rd party repository with these returned data, and then I'd like to inject this repository into on of my app's services. I'm looking for a proper, clean way of doing it, because the one that I currently have looks a bit hacky for me.
app.module.ts
content:
let repo; //this is what i'd like to avoid
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule
],
providers: [
{
provide: SomeService, useFactory: () => new SomeService(repo)
}
],
entryComponents: [AppComponent]
})
export class AppModule implements DoBootstrap {
ngDoBootstrap(app: ApplicationRef) {
//some async operation which returns context data
setTimeout((data) => {
repo = Some3rdPartyDatabaseSDK.init(data.token, data.repoConfig)
app.bootstrap(AppComponent);
}, 3000);
}
}
Can it be done better?
Upvotes: 0
Views: 192
Reputation: 4117
For this scenarios you should use, APP_INITIALIZER, This function is called when angular app is initialized.
Angular will execute provided function when the app is initialized. Angular will wait for the initialization if the function returns a promise until the promise resolved.
AppLoadService
in your projectAPP_INITIALIZER
in providers
.DEMO (Application will initialize after 5s)
app-load.service.ts
@Injectable()
export class AppLoadService {
repo: any;
init(): Promise<any> {
return new Promise((resolve, reject) => {
console.log('App is yet to initialize');
setTimeout(() => {
console.log('App initialized');
this.repo = 'some value';
resolve();
}, 5000);
});
}
}
app.module.ts
import { NgModule, APP_INITIALIZER } from '@angular/core';
function init_app(appLoadService: AppLoadService) {
return () => appLoadService.init();
}
@NgModule({
providers: [
AppLoadService,
{ provide: APP_INITIALIZER, useFactory: init_app, deps: [AppLoadService], multi: true }
]
})
export class AppModule { }
Upvotes: 1