Skip to content

Allow dynamic LOCALE_ID #47637

@vbraun

Description

@vbraun

Which @angular/* package(s) are relevant/related to the feature request?

core, language-service, localize

Description

Background

Dynamically changing the locale is now possible, that is, you can change the translations at any time during the life of the application without reload by calling

clearTranslations();
loadTranslations(newLocale);

and then recreating all components. The latter can be achieved by routing to a new page or recreating the router outlet, e.g.:

<router-outlet
    *ngFor="let item of [locale]">
</router-outlet>

It is understood that this only changes future calls to $localize, so developers have to ensure that translations are not cached in global variables, and in particular not cached in global services.

Problem

What is missing is a way to change LOCALE_ID dynamically, since that is provided as a string (i.e. a Javascript primitive). So e.g. the default locale of the DatePipe remains the initial locale.

Workaround

Since Angular always (I think) ends up calling this before using the value of LOCALE_ID

function normalizeLocale(locale: string): string {
    return locale.toLowerCase().replace(/_/g, '-');
}

we can just supply an object with a toLowerCase method:

class LocaleIdProvider {

    get localeStr(): string {
        ... return dynamic locale as string here ...
    }
    
    toLowerCase(): string {
        return this.localeStr.toLowerCase();
    }
}

@NgModule({
    provide: [{ provide: LOCALE_ID, useClass: LocaleIdProvider }]
})
export class AppModule {
    ...
}

Proposed solution

I propose to make that workaround official (but with toString instead of toLowerCase), that is, only require that LOCALE_ID has a toString() method instead of an actual string:

interface Stringifyable {
    toString(): string;
}

export const LOCALE_ID: InjectionToken<Stringifyable>;

This is a backward compatible change since strings are naturally stringifyable.

Alternatives considered

Our choices are:

  • Stick with the inofficial workaround, but that is fragile in case Angular starts using more string methods of LOCALE_ID.
  • Always supply the locale to the Angular DatePipe
  • Write our own date pipe that does not use LOCALE_ID.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: i18nIssues related to localization and internationalization

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions