In my backend, I have some API resources which return some configuration information to the frontend. Since I don't want to call them for each resource I show, I want to do it upfront.
From what I've seen, APP_INITIALIZER looks promising, so I tried it: https://stackblitz.com/edit/angular-ivy-4yfvtk?file=src/link.service.ts
But it is not able to inject the LinkService
.
I added the service with deps to the AppModule. I am not quite sure what the issue is. Furthermore, I've checked other topics, but as far as I can tell it is the same.
What am I missing?
CodePudding user response:
There are quite a few adjustments that you need to make in order for this to work:
- There is no provider for the LinkService, you should either provide it in root using
@Injectable({providedIn: 'root'})
or adding it in theproviders
array of theAppModule
- You need to import
HttpClientModule
in your app module, otherwise there is no provider forHttpClient
service. - The
LinkService
instance will be provided as the first parameter of the topmost function that you use as your factory method. It should look like this:
export function initLinkService(service: LinkService) {
return () =>
new Promise((resolve, reject) => {
console.log('before init', service);
service.init();
console.log('after init', service);
resolve(null);
});
}
Then the AppModule
registration changes to this:
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule],
declarations: [AppComponent, HelloComponent],
bootstrap: [AppComponent],
providers: [
LinkService,
{
provide: APP_INITIALIZER,
useFactory: initLinkService,
deps: [LinkService],
multi: true,
},
],
})
CodePudding user response:
You got it wrong little bit.
First, your init
funtion must return a function that produces a promise
export function initLinkService(service: LinkService) {
return () =>
new Promise((resolve, reject) => {
console.log('before init', service);
service.init();
console.log('after init', service);
resolve(null);
});
}
Then you have to actually provide LinkService
by including it into providers
section. Moreover, you have to import HttpClientModule
. Then you provide init
method directly
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule], //import
declarations: [AppComponent, HelloComponent],
bootstrap: [AppComponent],
providers: [
LinkService, // required provider
{
provide: APP_INITIALIZER,
useFactory: initLinkService, //pass factory method directly
deps: [LinkService],
multi: true,
},
],
Now, it will work https://stackblitz.com/edit/angular-ivy-4yfvtk?file=src/app/app.module.ts