1

I'm working on internationalisation of an Angular app where I need to dynamically detect the locale that the user has actively selected for the app (the user must actively switch locale for the site to be displayed in their preferred language).

In my root module I specify the following provider for TRANSLATIONS, where the required xlf file (the translations file) is determined dynamically using a factory that depends on the value of my LOCALE_ID:

app.module.ts

... imports go here

export function selectedLocaleFactory(): string {
  return LocaleService.getCurrentLanguage();
}

providers:
[
  LocaleService,
  {
    provide: TRANSLATIONS,
    useFactory: (locale) => {
      locale = locale || 'en'; // default to english if no locale provided
      return require(`raw-loader!../locale/messages.${locale}.xlf`);
    },
    deps: [LOCALE_ID]
  },
  {
    provide: LOCALE_ID,
    useFactory: selectedLocaleFactory
  }
]

As you can see, in the TRANSLATIONS provider, I'm determining the translation file to use based on the value of LOCALE_ID.

LOCALE_ID is determined by using another factory (selectedLocaleFactory), which simply tries to return a LOCALE_ID value using a method getCurrentLanguage from the LocalService. I'm not sure this is the correct/best way to get a value from my service - I mean selectedLocaleFactory isn't really acting as a true 'factory', and services are designed to be injected.

In any case, I get this compile error in app.module.ts:

Property 'getCurrentLanguage' does not exist on type 'typeof LocaleService'.

Here's an extract from my LocalService:

@Injectable()
export class LocaleService {

  private currLanguage: string;

  constructor( private router: Router ) {
         // this.currLanguage is set here - based on the URL being accessed by the user
  }

  getCurrentLanguage() { 
    return this.currLanguage;
  }

If I make getCurrentLanguage a static method inside the LocaleService it's still inaccessible:

  static getCurrentLanguage() { 
    return this.currLanguage;
  }

UPDATE:

I realised that I need to instantiate the service to access the appropriate method:

export function selectedLocaleFactory(): string {
  var localeService = new LocaleService(null);
  return localeService.getCurrentLanguage();
}

My LocaleService has a Router dependency, so I just set this to null. It still feels though like I'm trying to do this the wrong way. My LocaleService should really be a singleton and I'm concerned I may end up with issues using my current approach (for example issues with shadowing). Is there a more 'correct' I can access a property from my service inside my root module?

The answer by @Thierry Templier here - What is the best way to declare a global variable in Angular 2 / Typescript suggests bootstrapping the service to get access to one of its variables, however this approach gives me an error saying I can't use the service as an entry point.

Chris Halcrow
  • 21,541
  • 11
  • 115
  • 145

0 Answers0