Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(core): add syntactic sugar for initializers #53152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

yjaaidi
Copy link
Contributor

@yjaaidi yjaaidi commented Nov 24, 2023

Add a helper provider functions to simplify the use of INITIALIZER intializer tokens

  • provideAppInitializer() for APP_INITIALIZER
  • provideEnvironementInitializer() for ENVIRONMENT_INITIALIZER
  • providePlatformInitializer() for PLATFORM_INITIALIZER

This removes the boilerplate code for the initializers like:

{
   provide: APP_INITIALIZER,
   multi: true,
   useValue: initializerFn
}

in favor of:

provideAppInitilizer(initializeFn)

This also includes a schematic migration.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@yjaaidi yjaaidi force-pushed the feat/add-provide-app-initializer branch 2 times, most recently from b3e0ac1 to 7208d27 Compare November 25, 2023 09:37
@pkozlowski-opensource pkozlowski-opensource added the area: core Issues related to the framework runtime label Nov 27, 2023
@ngbot ngbot bot added this to the Backlog milestone Nov 27, 2023
@lacolaco
Copy link
Contributor

lacolaco commented Dec 2, 2023

To keep consistency with provideHttpInterceptors, probably we should choose provideAppInitializers(...initializers: InitializerFn[]). How do you think about it?

@yjaaidi yjaaidi force-pushed the feat/add-provide-app-initializer branch 2 times, most recently from 99f087c to 7058b62 Compare December 21, 2023 14:45
@yjaaidi
Copy link
Contributor Author

yjaaidi commented Dec 21, 2023

To keep consistency with provideHttpInterceptors, probably we should choose provideAppInitializers(...initializers: InitializerFn[]). How do you think about it?

Hey @lacolaco! I wonder if we really want to keep them consistent.
In most cases, you want to provide all your interceptors in one place with an array that makes the interceptors order explicit and easy to understand.

On the other hand, app initializers are often totally independent and even provided in different places like custom provide functions. (e.g. provideStore() { return [..., provideAppInitializer(store => store.init())] }
My guess is that in most cases there will be only one app initializer so writing provideAppInitializers([() => {}]) can be syntactically heavy with too many types of brackets in one line 😊

We could end up in a styleUrls / styles situation where the array was of a cardinality of one in most cases.

What do you think?

@lacolaco
Copy link
Contributor

lacolaco commented Dec 21, 2023

@yjaaidi As you says, each APP_INITIALIZER function is basically independent. I agree with your design 👍

@atscott
Copy link
Contributor

atscott commented Jan 22, 2024

@yjaaidi can you please update the commit to be a feat rather than refactor?

@yjaaidi
Copy link
Contributor Author

yjaaidi commented Jan 22, 2024

@yjaaidi can you please update the commit to be a feat rather than refactor?

Done!

We tried to make it ship before 17.1.0 😅 but you got us!
Cf. https://youtu.be/zno7FMKXbVQ?t=2010

@yjaaidi yjaaidi force-pushed the feat/add-provide-app-initializer branch from 7058b62 to 30fe7a6 Compare January 22, 2024 17:38
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Jan 22, 2024
@yjaaidi yjaaidi changed the title refactor(core): add provideAppInitializer syntactic sugar feat(core): add provideAppInitializer syntactic sugar Jan 22, 2024
@yjaaidi yjaaidi force-pushed the feat/add-provide-app-initializer branch from 30fe7a6 to 3ad1994 Compare January 22, 2024 18:36
Copy link
Member

@alxhub alxhub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

@alxhub alxhub added the target: minor This PR is targeted for the next minor release label Jan 22, 2024
@yjaaidi
Copy link
Contributor Author

yjaaidi commented Jan 22, 2024

👍 either way works for me.

@alxhub done here as there is a low risk this breaks anything and rolling back to the previous implementation is straightforward.

Now, all app initializers will run with injection context.

@atscott do you want me to squash the commits or keep them separated?

Copy link
Contributor

@atscott atscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@atscott
Copy link
Contributor

atscott commented Jan 22, 2024

@atscott do you want me to squash the commits or keep them separated?

What you have is fine

@yjaaidi
Copy link
Contributor Author

yjaaidi commented Jan 22, 2024

Thanks @atscott, @alxhub and @JeanMeche for your time!

Copy link
Member

@JoostK JoostK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to address in a follow-up as these are non-blocking.

@angular-robot angular-robot bot added the area: docs Related to the documentation label Jan 22, 2024
@yjaaidi
Copy link
Contributor Author

yjaaidi commented Jan 22, 2024

Now that the initializer is running within an injection context even without using the helper, I update the reference docs with simplified examples. What do you think?

I'd prefer replacing the following APP_INITIALIZER docs example:

 function initializeApp() {
   const http = inject(HttpClient);
   return firstValueFrom(
     http
       .get("https://someUrl.com/api/user")
       .pipe(tap(user => { ... }))
   );
 }

with something simpler even though more abstract like this:

function initializeApp(): Promise<unknown> {
  return inject(MyService).init();
}

This could be fixed in a distinct PR.

cc. @alxhub @atscott @JeanMeche @JoostK

@yjaaidi yjaaidi force-pushed the feat/add-provide-app-initializer branch from 6ba3a73 to a501983 Compare January 23, 2024 00:01
Copy link
Member

@JeanMeche JeanMeche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a docs perspective.

@alxhub alxhub self-assigned this Sep 26, 2024
@pullapprove pullapprove bot removed the request for review from atscott October 17, 2024 16:55
@@ -9,6 +9,11 @@
"version": "19.0.0",
"description": "Updates ExperimentalPendingTasks to PendingTasks",
"factory": "./bundles/pending-tasks#migrate"
},
"provide-initializer": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this migration is safe to run automatically. The provider functions in this PR return EnvironmentProviders (as they should) but existing usages may not be typed in a way to handle that type.

We can exclude it and use it as an optional migration for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: to make it optional you can just add “optional”: true

Copy link
Contributor Author

@yjaaidi yjaaidi Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!
What would be the solution to make it automatic for v20?
We could detect where it is used and transform when it is safe. When it's not safe what would be the fallback? A type cast? A compact function? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx @JeanMeche for handling this while I'm AFK 😊

@angular-robot angular-robot bot added area: core Issues related to the framework runtime and removed area: core Issues related to the framework runtime labels Oct 21, 2024
@JeanMeche JeanMeche added action: merge The PR is ready for merge by the caretaker target: major This PR is targeted for the next major release and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Oct 22, 2024
@AndrewKushnir AndrewKushnir added action: presubmit The PR is in need of a google3 presubmit and removed target: major This PR is targeted for the next major release labels Oct 22, 2024
@AndrewKushnir
Copy link
Contributor

Presubmit.

@AndrewKushnir AndrewKushnir removed the action: presubmit The PR is in need of a google3 presubmit label Oct 22, 2024
@AndrewKushnir
Copy link
Contributor

This PR was merged into the repository by commit 19edf2c.

The changes were merged into the following branches: main

Copy link
Contributor

@pawelfras pawelfras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
thank you @yjaaidi for your great work!
The deprecation version mentioned in JSDocs for APP_INITIALIZER and PLATFORM_INITIALIZER is 18.1.0. Shouldn't this be changed to 19.0.0 as it was done for ENVIRONMENT_INITIALIZER?
If so, here's my PR with this small adjustment: #58322

@@ -25,7 +34,12 @@ import {isPromise, isSubscribable} from '../util/lang';
* The function is executed during the application bootstrap process,
* and the needed data is available on startup.
*
* Note that the provided initializer is run in the injection context.
*
* @deprecated from v18.1.0, use provideAppInitializer instead
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @deprecated from v18.1.0, use provideAppInitializer instead
* @deprecated from v19.0.0, use provideAppInitializer instead

@@ -49,6 +49,11 @@ const DEFAULT_APP_ID = 'ng';

/**
* A function that is executed when a platform is initialized.
*
* @deprecated from v18.1.0, use providePlatformInitializer instead
Copy link
Contributor

@pawelfras pawelfras Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @deprecated from v18.1.0, use providePlatformInitializer instead
* @deprecated from v19.0.0, use providePlatformInitializer instead

@yjaaidi
Copy link
Contributor Author

yjaaidi commented Oct 23, 2024

Nice catch Pawel!

* ```
* createEnvironmentInjector(
* [
* provideEnvironmentInjector(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be provideEnvironmentInitializer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good one! Would you like to make a PR to fix this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just opened #58355 :)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker adev: preview area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.