1

I know that the following code doesn't work, because the translation file en.json hasn't been loaded, when ngOnInit() is called:

component.ts

ngOnInit() {
  console.log(this.translocoService.translate('hello', { value: 'world' }););
}

en.json

{
  "hello": "Hello",
}

An alternative would be subscribing to:

ngOnInit() {
  this.translocoService.selectTranslate('hello', { value: 'world' }).subscribe(value => console.log(value));
}

But in my component I have 30 keys that need to be translated. Should I really subscribe to all of the 30 keys?

Demo: https://stackblitz.com/edit/ngneat-transloco-8xqjqm?file=src%2Fapp%2Fapp.component.ts

dewey
  • 809
  • 2
  • 16
  • 47

4 Answers4

3

Now I found an even better solution: https://ngneat.github.io/transloco/docs/recipes/prefetch/#prefetch-the-user-language

I now use the APP_INITIALIZER to preload the translation file, before the app initializes. That way the translations are always available, also in the constructor of components.

This approach is unfortunately nested in the Transloco docs to be easiliy overlooked.

dewey
  • 809
  • 2
  • 16
  • 47
  • I'm still struggling with translations seemingly not being available fast enough with this implementation, https://ngneat.github.io/transloco/docs/translation-api/ doesn't seem to document the `load()` function which sounds like it could be a dispatch and not a guarantee of completion – MattTreichel Jan 30 '23 at 23:10
  • Sounds to me like a falsy implementation, when you are using functions for the initial loading of the translations. At least I haven‘t used any functions, instead I had just imported the Transloco module – dewey Feb 01 '23 at 07:33
1

I think that you should organize your JSON translation file to have a parent attribute containing all of your 30 translations required by your component (let's call the parent attribute parentAttribute, but find a better name ;)) :

{
  "parentAttribute": {
    "child1": "translation1"
    ...
    "child30": "translation30"
  }
}

Then, you should use the translateObject method provided by the transloco service :

const translations = this.translocoService.translateObject('parentAttribute');

translations variable should contain :

{
    "child1": "translation1"
    ...
    "child30": "translation30"
}
ppeinado
  • 61
  • 3
  • If my component would need 30 translations that doesn't exist already in the translations file, then yes this is a suitable solution. But half of the translations are already used in other components. So with your approach I would need to C&P the translations in the `parentAttribute` – dewey Nov 15 '21 at 07:23
  • 1
    Ok I understand your problem. You don't need to really C&P, but you can refer to an existing translation (see [this link](https://ngneat.github.io/transloco/docs/additional-functionality)). Sometimes you need to do that because you can't organize your translations so that it will be easy to pick them from different part of your app – ppeinado Nov 15 '21 at 10:52
  • Thank you, that was the last missing piece! – dewey Nov 15 '21 at 12:27
0

Not sure if i understand correctly your need, but could be AfterViewInit the right lifecycle hook for you? At that point, transloco has loaded the translation files and you don't need to subscribe anymore.

Luca Farsetti
  • 257
  • 2
  • 14
  • 1
    Just found a good solution, please look at the other answer. Using AfterViewInit looks to me like a not so good solution, because you can't guarantee that the translation files have been loaded – dewey Nov 15 '21 at 12:34
-1

You may subscribe to the event objects, which fires when a language file is loaded. See the documentation

ngOnInit() { // or even constructor

  this.translocoService.events$.subscribe(
    (event: TranslocoEvents) => {
      if (event.type === 'translationLoadSuccess') {

        console.log(this.translocoService`enter code here`.translate('hello', { value: 'world' }););
        // Do translation stuff

      }
    });

}
Katsche
  • 9
  • 1
  • 1
    I also tried this and it's a bad solution, because the `translationLoadSuccess` only get's called when the translation file gets _initially_ loaded. So when you login in your application and navigate to the component, then this event has already been fired and your code will never be executed. – dewey Nov 17 '21 at 12:26