Skip to content
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

LOCALE_ID is being set before APP_INITIALIZER finish execution - [ng serve only] #34701

Closed
1 of 15 tasks
TomaszCz opened this issue Jan 9, 2020 · 4 comments
Closed
1 of 15 tasks
Labels
area: core Issues related to the framework runtime area: i18n
Milestone

Comments

@TomaszCz
Copy link

TomaszCz commented Jan 9, 2020

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • xi18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Yes. It is a breaking change.

Description

LOCALE_ID is being set before APP_INITIALIZER function finish execution.
Interestingly, this behavior can be observed only with ng serve. Both repositories will work fine on stackblitz.

🔬 Minimal Reproduction

Here is the reproduction repo:
https://stackblitz.com/github/TomaszCz/angular-ivy-LOCALID
and the same repo after ng update @angular/core @angular/cli --next
https://stackblitz.com/github/TomaszCz/angular-ivy-LOCALID/tree/angular9

clone and run ng serve the updated one will not work - the locale value will be undefined.

🔥 Exception or Error

After update:
image

Before the update:
image

🌍 Your Environment

Before update:


C:\a\AngularPOC\angular>ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.22
Node: 12.3.1
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.22
@angular-devkit/build-angular     0.803.22
@angular-devkit/build-optimizer   0.803.22
@angular-devkit/build-webpack     0.803.22
@angular-devkit/core              8.3.22
@angular-devkit/schematics        8.3.22
@angular/cli                      8.3.22
@ngtools/webpack                  8.3.22
@schematics/angular               8.3.22
@schematics/update                0.803.22
rxjs                              6.5.4
typescript                        3.5.3
webpack                           4.39.2

After update:


C:\a\AngularPOC\angular>ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 9.0.0-rc.8
Node: 12.3.1
OS: win32 x64

Angular: 9.0.0-rc.8
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.0-rc.8
@angular-devkit/build-angular     0.900.0-rc.8
@angular-devkit/build-optimizer   0.900.0-rc.8
@angular-devkit/build-webpack     0.900.0-rc.8
@angular-devkit/core              9.0.0-rc.8
@angular-devkit/schematics        9.0.0-rc.8
@ngtools/webpack                  9.0.0-rc.8
@schematics/angular               9.0.0-rc.8
@schematics/update                0.900.0-rc.8
rxjs                              6.5.4
typescript                        3.6.4
webpack                           4.41.2

I see similar closed issue
#31465
and the fix 08c449d

#31983

@alan-agius4 alan-agius4 transferred this issue from angular/angular-cli Jan 9, 2020
@ngbot ngbot bot added this to the needsTriage milestone Jan 9, 2020
@AndrewKushnir AndrewKushnir added the area: core Issues related to the framework runtime label Jan 9, 2020
@petebacondarwin
Copy link
Member

petebacondarwin commented Jan 16, 2020

The problem is indeed that we are setting the locale (for ivy) before the application initialisers run.

We had to do this (at the moment) because the $localize messages are processed when the module loads (i.e. the es6 module) which require the locale to be set.

If we move the $localize calls inside a closure that only gets run when the template is being processed then this restriction is removed and we could put the initialisation of the locale later in the bootstrap (i.e. after the initializers have run).

I think this analysis is actually incorrect. I think we can just move the code...

@petebacondarwin
Copy link
Member

This PR (#31465) effectively fixed it for non-ivy because the getting of LOCALE_ID via the injector is only done under ivy. But there is a test there which is incorrectly passing under ivy:

it('should wait for APP_INITIALIZER to set providers for `LOCALE_ID`', async() => {
let locale: string = '';
const promise = Promise.resolve().then(() => { locale = 'fr-FR'; });
const testModule = createModule({
providers: [
{provide: APP_INITIALIZER, useValue: () => promise, multi: true},
{provide: LOCALE_ID, useFactory: () => locale}
]
});
const app = await defaultPlatform.bootstrapModule(testModule);
expect(app.injector.get(LOCALE_ID)).toEqual('fr-FR');
});

petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jan 17, 2020
Before ivy it was possible to configure a mutable service value
in an application initializer (by providing an `APP_INITIALIZER`)
that could be read in the provider of `LOCALE_ID`. This is a common
scenario if you wanted to load the locale id asynchronously from
an HTTP request for instance.

When using the ivy, the runtime needs to be told what the current
locale is, which is done by calling the `setLocaleId()` function with
the value injected by the `LOCALE_ID` token. Previously this was
being done before the application initializers were run, which meant
that the `LOCALE_ID` provider was being executed before the
app initializers had a chance to get a new value for it.

Now this initalization of the locale for the ivy runtime is done after the
application initializers have been run.

Closes angular#34701
petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jan 17, 2020
Before ivy it was possible to configure a mutable service value
in an application initializer (by providing an `APP_INITIALIZER`)
that could be read in the provider of `LOCALE_ID`. This is a common
scenario if you wanted to load the locale id asynchronously from
an HTTP request for instance.

When using the ivy, the runtime needs to be told what the current
locale is, which is done by calling the `setLocaleId()` function with
the value injected by the `LOCALE_ID` token. Previously this was
being done before the application initializers were run, which meant
that the `LOCALE_ID` provider was being executed before the
app initializers had a chance to get a new value for it.

Now this initalization of the locale for the ivy runtime is done after the
application initializers have been run.

Closes angular#34701
@matsko matsko closed this as completed in e0ad9ec Jan 17, 2020
matsko pushed a commit that referenced this issue Jan 17, 2020
Before ivy it was possible to configure a mutable service value
in an application initializer (by providing an `APP_INITIALIZER`)
that could be read in the provider of `LOCALE_ID`. This is a common
scenario if you wanted to load the locale id asynchronously from
an HTTP request for instance.

When using the ivy, the runtime needs to be told what the current
locale is, which is done by calling the `setLocaleId()` function with
the value injected by the `LOCALE_ID` token. Previously this was
being done before the application initializers were run, which meant
that the `LOCALE_ID` provider was being executed before the
app initializers had a chance to get a new value for it.

Now this initalization of the locale for the ivy runtime is done after the
application initializers have been run.

Closes #34701

PR Close #34830
@TomaszCz
Copy link
Author

I can confirm it is working now on 9.0.0-rc.10. Thank you!

@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 Feb 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime area: i18n
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants