I had the following code where I want the storage to init first, then the session, and then you shall enter the app.
export function initApp(
storage: StorageService,
session: SessionService,
) {
return async () => {
await firstValueFrom(
storage.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
),
)
await firstValueFrom(
session.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
),
)
}
}
I used to implement it like follow
{
provide: APP_INITIALIZER,
useFactory: initApp,
deps: [StorageService, SessionService],
multi: true,
},
But with the latest provideAppInitializer I cannot find the way to provide deps to my method.
It does seems the angular team have changed the way to use useFactory
to implement it as follow :
provideAppInitializer(() => {
const initializerFn = ((service: Service) => {
return () => service.init();
})(inject(Service));
return initializerFn();
});
But I cannot wrap my head arround where to give my dependences.
Does somebody have any idea ?
Just inject it and use it.
Make sure the init method returns a promise.
provideAppInitializer(() => {
const service: Service = inject(Service);
return service.init();
});
If you want the initialization to happen sequentially, then use switchMap
instead.
provideAppInitializer(() => {
const storage: StorageService = inject(StorageService);
const session: SessionService = inject(SessionService);
return firstValueFrom(
storage.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
switchMap(() => {
return session.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
)
})
),
);
});
You can simplify your code to:
provideAppInitializer(() => {
const storage: StorageService = inject(StorageService);
const session: SessionService = inject(SessionService);
return firstValueFrom(
forkJoin([
storage.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
),
session.initialized$.pipe(
filter((event) => (event ? true : false)),
take(1),
),
])
);
});