We have an approach for lazy loading and setting the LOCALE_ID of the Angular application from the API (by loading the user profile data during on startup). This worked fine on Angular 7 but when I've upgraded to Angular 8 it stopped working. When the localeFactory is called (see below) the localeService.getLocale() is undefined, it has not been initialized yet.
We initialize it in a SharedResolver which is in a SharedModule which is included in the imports of the AppModule.
What is the right approach for doing this in Angular 8? In didn't see anything specific to this in the documentation of changes so I guess it's something indirect.
Any input on what approach I should take here? Thanks
Please see relevant code below:
app.module.ts
export function localeFactory(localeService: LocaleService) {
    console.log('locale factory called');
    // This is `undefined` here now for some reason
    console.log(localeService.getLocale());
    return localeService.getLocale() || 'en';
}
...
const APP_LOCALE_ID = {
    provide: LOCALE_ID,
    deps: [LocaleService],
    useFactory: localeFactory
};
@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpClientModule,
        BrowserAnimationsModule,
        AppRoutingModule,
        SharedModule.forRoot(), // <- in this module we have the SharedResolver
        AccountModule,
        ApiModule,
        GenesysSubprojectModule
    ],
    declarations: [AppComponent],
    providers: [
        AppRouteGuard,
        BreadcrumbService,
        {
            provide: APP_INITIALIZER,
            useFactory: appInitializerFactory,
            deps: [PlatformLocation, BootstrapService],
            multi: true
        },
        { provide: ErrorHandler, useClass: GlobalErrorHandler },
        AppRouteGuard,
        BreadcrumbService,
        // TODO - This doesn't work anymore!
        APP_LOCALE_ID
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
shared-resolve.ts
export class SharedResolve implements Resolve<any> {
    ...
    resolve(route: ActivatedRouteSnapshot) {
       ...
        const observables = forkJoin(
            this.authService.getPermissions(),
            this.authService.getCurrentProfileFromApi(),
            this.languageApi.getActiveLanguages(), // TODO - cache
            this.tenantSettingsApi.getLogo(logoLastModificationTime),
            this.dashboardApi.getDashboardSettings(),
            this.reportApi.getReportSettings(),
            this.publicSettingsApi.getSettings(),
            this.tenantSettingsApi.getInitializationSettings()
        ) as Observable<any[]>;
        return observables
            .pipe(
                flatMap(result => {
                    ...
                    const profile: CurrentUserProfileExtEditDto = result[1];
                    ...
                    const languageName =
                        profile.languageName || navigator.language; // browser default language
                    console.log('Set locale to languageName=' + languageName);
                    this.storageService.setLocale(languageName);
                    this.localeService.setLocale(languageName);
                Yep, that's an Ivy i18n issue in v8.x.x. I've posted it in the Angular repo and has been confirmed by @Ocombe (who is working on Ivy i18n).
If you are in a hurry, as a workaround, you can do this:
As Ivy is searching for a runtime locale, you can simply provide a default language in the AppModule like this and then provide your APP_INITIALIZER:
...
providers: [
    ...
    { provide: LOCALE_ID, useValue: 'en' }
    {
        provide: APP_INITIALIZER,
        useFactory: initializeAppSettings,
        deps: [AppInitializerService],
        multi: true
    }
    ...
]
...
This will first set the default locale and then run your APP_INITIALIZER. Next, in your CoreModule (only loaded once), simply provide the new LOCALE_ID fetched from the backend:
...
providers: [
    ...
    {
        provide: LOCALE_ID,
        useFactory: (localeService: LocaleService) => localeService.getCurrentLocale(),
        deps: [LocaleService]
    }
    ...
]
...
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With