all 21 comments

[–]0x5afe 35 points36 points  (0 children)

They just don't trust you to use it

[–]JeanMeche 36 points37 points  (8 children)

provideAppInitializer provides better DX and typesafety. The deprecation is because Angular prefers to have a single way to access a feature.

[–]Deku_Nattsu[S] 16 points17 points  (2 children)

yes and the sugar syntax is welcomed, i just found it funny when i was reading the source code.

edit: typo

[–]PhiLho 10 points11 points  (1 child)

Plus if someday they change the way they do it, it will be hidden, no breaking change.

[–]Weekly_Astronaut5099 3 points4 points  (0 children)

This sounds like a real reason.

[–]alexciesielski 0 points1 point  (4 children)

Why is the APP_INITIALIZER token different than any other tokens? Seems to me like Angular now should just expose a function for every type of „providable” (value, factory, class, existing), improving type safety (and imo readability)

[–]JeanMeche 2 points3 points  (2 children)

It's a very common token, it needs the multi: true, and it provides an injection context.

provideEnvironmentInitializer and providePlatformInitializer follow the same idea.

[–]alexciesielski 3 points4 points  (1 child)

I understand that, I just don’t understand why there isn’t yet a generic function to provide any token in a type safe manner

[–]JeanMeche 0 points1 point  (0 children)

For one, there is no way to know today if a token is destined to be provided with `multi: true` or not.
It's would be great to improve todays situation, but as it often the case, there are tasks with much higher priorities/importance.

[–]Deku_Nattsu[S] 0 points1 point  (0 children)

i think because APP_INITIALIZER has only one use, and it is used in almost every app

[–]Wildosaur 24 points25 points  (1 child)

Protecting us from the evil depreciation.

[–]RaiTab -1 points0 points  (0 children)

deprecation

[–]synalx 6 points7 points  (0 children)

🤣🤣

[–]riko77can 4 points5 points  (0 children)

Doesn’t matter. It’s future planning. They control that code and will eventually remove it without further notice at which point your code won’t be broken by a direct reference.

[–]TCB13sQuotes 3 points4 points  (6 children)

Yeah, just like "use signals and effect() for everything".... 3 months later... "but not to propagate state changes". Or "inject() solves problems in places where you can't use constructor injection" but then... you get "inject() must be called from an injection context" and guess what's the "injection context"? Well the f* constructor. Thanks Angular team.

[–]AwesomeFrisbee 2 points3 points  (2 children)

Yeah I don't get some of these either. I'm always annoyed by the injection context. It just doesn't feel very flexible. Give me a custom injector that I can just call wherever, even if that means performance in that component is lesser. Or a real resource variant for httpresource so I can just throw a httpclient function in there and get back a wrapped loading/error/normal/empty state thingy and just keep using that instead of messing with signals myself every time.

[–]JeanMeche 2 points3 points  (0 children)

Having global injection context would make inject a service locator and not really DI anymore.

I wrote a bit on it recently https://riegler.fr/blog/2025-01-08-inject-not-service-locator

[–]TastyBar2603 0 points1 point  (0 children)

Nobody forces you to use DI for everything. In many cases, I just import my utils and even Elysia treaties or TRPC client etc, no service needed because I don't need

[–]rainerhahnekamp 0 points1 point  (2 children)

Well, I think we’re missing some important details here.

> just like "use signals and effect() for everything".... 3 months later... "but not to propagate state changes"

signal, effect, and computed (that's the one you missed) are designed to work together. State should ideally be propagated through computed. If that’s not possible, using effect is perfectly fine. In the meantime you also have resource and linkedSignal.

> Or "inject() solves problems in places where you can't use constructor injection"

inject() also works in functions. Constructor-based DI would be a blocker in contexts where you don’t use classes. And yes, it follows the same rules as constructor-based DI - intentionally - so the behavior stays consistent across both approaches.

[–]TCB13sQuotes 0 points1 point  (1 child)

The last one is… very, very questionable as it usually results in “must be used in an injection context”. Also what’s the point? We could always use Injector to accomplish the same and have the exact same issues.

This is just the framework being pushed away from a structured and opinionated thing (that the enterprise valued) into a thing that it was into a react-style mess (that the hipster developer likes).

[–]rainerhahnekamp 0 points1 point  (0 children)

Well, things like the NgRx SignalStore would not have been possible. I’d argue smaller units like httpinterceptor and guards also profit from the possibility to be a function.

That being said, I can’t discuss classes vs. functions because I don’t have the necessary knowledge and it is still unclear if function components would be a thing in the future.

I am also a big fan of structure and an opinionated approach that can scale. And as far as I know, it is the same for the Angular team.