Search code examples
angulartransloco

How to check if a translation file has been loaded in transloco?


I have an Angular 14 project to which I recently added transloco. It works well, but it also uses some PrimeNG to which I must provide the right i18n translations every time the language is switched.

This is what I have right now:

  ngOnInit(): void {
    this.translocoService.events$
      .pipe(filter(e => e.type === 'langChanged'))
      .subscribe(() => this.loadTranslations());
    this.translocoService.events$
      .pipe(filter(e => e.type === 'translationLoadSuccess'))
      .subscribe(() => this.loadTranslations());
  }

  setEs(): void {
    this.translocoService.setActiveLang("es");
  }

  setCa(): void {
    this.translocoService.setActiveLang("ca");
  }

  private loadTranslations() : void {
    console.log("CARGANDO TRADUCCIONES");
    this.config.setTranslation({
      monthNames : [
        this.translocoService.translate("tiempo.mes.enero"),
        this.translocoService.translate("tiempo.mes.febrero"),
        this.translocoService.translate("tiempo.mes.marzo"),
        ... [lots of translations, 34 in total]
      ]};
  }

This works well, but the first time I switch languages I get lots of errors in the console warning me that the translations are not yet ready:

ngneat-transloco.mjs:284 Missing translation for 'tiempo.diamin.sabado'

It seems to me that it is due the subscription being launched for 'langChanged' while it still has not had time to load the translation.

Now, other approachs that I have tried do have problemas:

  • If I remove the subscription for langChanged, then it only updates the values the first language change (because the translation is only loaded the first time, so translationLoadSuccess is not going to be fired again).

  • If I remove the subscription for translationLoadSuccess, the first time I switch languages it does not update the values correctly, because the translations have not been loaded when the langChanged event is processed.

How should I deal with it?


Solution

  • I have worked my way around it by prefetching the translations. It works for me because I will have few languages (2 right now, 4 tops) and the app is not that big, but it could be not practical for other people.

    I will leave the question unresolved until a "proper" answer is given, but I hope this helps others:

      ngOnInit(): void {
        let activeLanguage = this.translocoService.getActiveLang();
        this.translocoService.load(activeLanguage).subscribe(() => this.loadTranslations());
        for(var language of this.translocoService.getAvailableLangs()) {
          if (typeof language === "string") {
            if (activeLanguage !== (language as string)) {
              this.translocoService.load(language as string).subscribe();
            }
          } else {
            let lang = language as LangDefinition;
            if (activeLanguage !== lang.id) {
              this.translocoService.load(lang.id).subscribe();
            }
          }
        }
        
        this.translocoService.events$
          .pipe(filter(e => e.type === 'langChanged'))
          .subscribe(() => this.loadTranslations());
      }
    

    Note: I did all of this in the component logic, but I think it would be better as a service and I will move into it.