Reputation: 2796
We need some services in our application right from the start. Therefore we have some providers, that initialize them on startup. This is from the providers
section in app.module.ts
:
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'en-US' },
{
provide: APP_INITIALIZER,
useFactory: (service: MetaService) => () => service,
deps: [MetaService],
multi: true
}
],
This worked fine in Angular 9-11. However, after upgrading to Angular 12 and even in a blank Angular 12 project, this seems to break the application.
The service is created though. It's correctly logged using this:
useFactory: (service: MetaService) => () => { console.log(service); return service; },
However, the page comes back as blank white one. No component is rendered, no routing did happen.
There are no errors on the CLI and nothing in the browser's console, just a blank page. When I remove the provider, it seems to work fine.
Did they change, how APP_INITIALIZER
works in Angular 12? How to fix or update the code to make it work again? Maybe there's a better way to initialize services on startup anyway?
Upvotes: 2
Views: 1996
Reputation: 20524
Angular changed it app initializer functionality to allow for Observables as well as Promises. What's also changed is the specificity of the injection token, which expects a function that returns a promise, observable or void. So as of now, your code is bad since you're returning a service instead of one of the expected types. That still doesn't explain what's going wrong.
Angular used to just check if the factory function for each initializer returned a promise and added it to an array of promises to execute with Promise.all(). Now, it is also checks if it is an observable and converts to a promise by wrapping a subscribe call in a promise and tying together the complete and error Observable callbacks to the resolve and reject Promise callbacks.
If you have a method called subscribe on your service then this would cause your service to pass Angular's isSubscribable guard. Then Angular would treat your service like an Observable and try to convert it to a promise in the fashion mentioned above. (If you have a then method then that would also cause a problem though that is unlikely given that your code worked before). The promise would never resolve and that would lead to the behavior you're describing.
There's no other reason I could imagine that would cause this issue given the code you've shared. At the very least just change the factory definition so it returns void and you should be good.
useFactory: (service: MetaService) => () => { }
Upvotes: 2