Core: translate directive doesn't update the text when changing the language via use() function

Created on 5 Jan 2017  路  22Comments  路  Source: ngx-translate/core

Hello,

First of all, thanks for the wonderful library. It was very easy and straight forward to get it up and running.

The issue

Unfortunately, I do have an issue when I try to switch to another language. The translate directive doesn't update the texts. Texts that are translated via the pipe do get updated.

In my AppComponent, I set the inital language to 'nl'.

export class AppComponent {
    constructor(private translateService: TranslateService) {
        // this language will be used as a fallback when a translation isn't found in the current language
        translateService.setDefaultLang('en');

         // the lang to use, if the lang isn't available, it will use the current loader to get them
        translateService.use('nl');
    }
}

In my view, there's

<div [translate]="'member.firstname'">First Name</div>
<div>{{ 'member.firstname' | translate }}</div>

Somewhere in my application, I have a button to switch the language to english, which calls

this.translateService.use('en');

When I click the button, the pipe does its thing, but the directive does not.

Presumable cause

When checking translate.directive.ts, I noticed that the node.lastKey is always equal to key, and that's why the translation does not occur.

updateValue(key: string, node: any, translations: any) {
        if(key) {
            let interpolateParams: Object = this.translateParams;
            if(node.lastKey === key && this.lastParams === interpolateParams) {
                return;
            }

When I comment it out (the check "if (node.lastKey ..."), the translation does occur and it works fine.
The if statement is probably there for a reason, but I guess that the fact the language changed should be added to the check as well.

I use version of g2-translate, and version 2.3.1 of angular.

Could you please have a look at this?

Thanks,
Jeroen.

need to check bug

Most helpful comment

As everyone I have a same issue where the translations are getting updated with translate pipe but not with other methods like .instant() or .get();
The only work around seems to be working is below

this.prop = translateService.instant('MY_TRANSLATE_KEY');
this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
     // do something
     this.prop = event.translations['MY_TRANSLATE_KEY']; // setting this again 
});

Is this solved or can anyone suggest better workaround here?

All 22 comments

Hi, I think I have a change like that coming up in the next version that I haven't pushed yet, I'll check when I get back home.

This has been fixed by the way, sorry for not replying before! Closing the issue :)

Hi, this doesn't seem to be fixed in the 6.0.0 version. Can you please check and release a new version?

I created a plunkr which shows that it is working. http://plnkr.co/edit/sR37RHoqxAHLWNViCLPX?p=preview

@ocombe I used the key as content of the h2 tag which works. But when I use it like this <h2 [translate]="'HOME.TITLE'"></h2> it doesn't show anything. Any ideas?

yes, it's a bug, it will be fixed in the next beta (currently fixed on master)
the directive doesn't work with empty text content right now, if you cannot wait for the next release, just put anything into the content like <h2 [translate]="'HOME.TITLE'">test</h2>

I have a similar issue with:

  • Ionic 3

    • Angular 5.03

    • ngx-translate 8.00

I have a template like you suggest:

<h2 [translate]="'WELCOME_HELLO_TEXT'">test</h2>

and I have 4 languages (en.json, fr.json, es.json and ga.json)

  • I save the current language in Storage and load it when the app starts with the initTranslate()function on my app.components.ts
  • When I change the language, I save the new language to Storage and try to load the new language with translate.use('fr')
  • The new language works if I reload the page (F5)

When I debug the app on the browser I found the next problem:

  • If my current language is English (en) and I change to another one (fr, es or ga) the translation isn't updated on the template until I reload the page (F5). (The template show the untranslated text like WELCOME_HELLO_TEXT)

  • If my current language is Fran莽ais, Galego or Espa帽ol I can change to English and the template gets updated accordingly but I cannot change these combinations:

    • fr -> es, ga
    • es -> fr, ga
    • ga -> fr, es

For the last 3 combinations I need to reload the page with F5 because when I change language I see the raw text like WELCOME_HELLO_TEXT

Any clue what I'm doing wrong ? The thing I cannot understand is why changing to English always works but changing to another language doesn't, and If I reload the page all languages works.

This is my initTranslate() on my app.components.ts:

  initTranslate() {
    // Set the default language for translation strings, and the current language.
    this.translate.setDefaultLang('en');
    const browserLang = this.translate.getBrowserLang();

    if (this.currentLanguage){
      this.translate.use(this.currentLanguage);
    }else if (browserLang) {
      if (browserLang === 'zh') {
        const browserCultureLang = this.translate.getBrowserCultureLang();

        if (browserCultureLang.match(/-CN|CHS|Hans/i)) {
          this.translate.use('zh-cmn-Hans');
        } else if (browserCultureLang.match(/-TW|CHT|Hant/i)) {
          this.translate.use('zh-cmn-Hant');
        }
      } else {
        this.translate.use(this.translate.getBrowserLang());
      }
    } else {
      this.translate.use('en'); // Set your language here
    }

    this.translate.get(['BACK_BUTTON_TEXT']).subscribe(values => {
      this.config.set('ios', 'backButtonText', values.BACK_BUTTON_TEXT);
    });
  }

and this is how I init ngx-translate on my app.module.ts:

@NgModule({
  declarations: [
    MyApp
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (createTranslateLoader),
        deps: [HttpClient]
      }
    }),
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot()
  ],
 ....



same issue

i have the same issue with:
Angular 5.22
ngx-translate 9.11

@AlvaroAV just same issue like you

i use ionic 3
angular 5.0.3

"@ngx-translate/core": "^9.1.1",
"@ngx-translate/http-loader": "^2.0.1"

the language change correctly on first app launch in the app.component.ts but after that when i change the language nothing change
and when i subscribe to onLangChange event it return lang: 'en' correct but translations: {} empty object
i don't know what is the problem i use this great library on different projects and it work very well
thanks

Same config as @FahmiChaar, same problem as @AlvaroAV.
The onLangChange returns the correct lang AND filled translations {}
But the screen does not update.

<h2 [translate]="'title.login'"></h2>

and

<ion-title>{{ "title.login" | translate }}</ion-title>

both not working

I also have the selected language in storage. If storage contains 'en' or is empty the language switch is not working. If the storage contains 'fr' on startup the switch to 'en' works ok!

same problem here, has it been solved by anyone?

Thank you very much for taking the time to post that link!
It contains very nice workarounds that solved my problem!

I know this issue is closed for a long time, but I have a similar problem, it only the translated text of the current component.

Imagine I have navigation.component.html where I have a button to toggle the language, translation here update fine.
And I have contact.component.html to update translation here, I have to refresh the page.

I am using :
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"@angular/core": "^6.1.0"

I have a nice workaround for the problem
Requires an service in that service:

  public selectedLang = new Subject<any>();

in your root component or app.component.ts subscribe to the above language

    this.theCreatedServiceHere.selectedLang.subscribe(lang => {
         this.translate.use(lang);
    }); 

Created with reference to the comments above

Same issue here.
"@angular/core": "^7.0.0",
"@ngx-translate/core": "^11.0.0",

I have a simple language selector component : translate.use(lang);
The view gets updated if use it like this :
<h3 class="pb-2 mt-4 mb-4" [translate]="'profile.name.title'"></h3> or <h3 class="pb-2 mt-4 mb-4" translate>profile.name.title</h3>

But if I use it like this I have to reload the page so the view gets updated :

<h3 class="pb-2 mt-4 mb-4" translate>
    profile.name.title
  </h3>

Same issue as @Exlord with

"@angular/core": "^6.1.8",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",

Some blocks with translate directive are getting updated, while others remain in previosly selected language.
Pipe seems to be working correctly though.
{{'text'|translate}}
"@ngx-translate/core": "^11.0.1", "@ngx-translate/http-loader": "^4.0.0",

Same issue as @lexigren with

"@angular/core": "~7.1.4"
"@ngx-translate/core": "^11.0.1"
"@ngx-translate/http-loader": "^4.0.0"

It's working with

"@angular/core": "~7.1.4"
"@ngx-translate/core": "^10.0.0"
"@ngx-translate/http-loader": "^3.0.1"

and again not in

"@angular/core": "~7.1.4"
"@ngx-translate/core": "^10.0.1"
"@ngx-translate/http-loader": "^3.0.1"

Looks like following commit #819 introduced problem

Hello,

First of all, thanks for the wonderful library. It was very easy and straight forward to get it up and running.

The issue

Unfortunately, I do have an issue when I try to switch to another language. The translate directive doesn't update the texts. Texts that are translated via the pipe do get updated.

In my AppComponent, I set the inital language to 'nl'.

export class AppComponent {
    constructor(private translateService: TranslateService) {
        // this language will be used as a fallback when a translation isn't found in the current language
        translateService.setDefaultLang('en');

         // the lang to use, if the lang isn't available, it will use the current loader to get them
        translateService.use('nl');
    }
}

In my view, there's

<div [translate]="'member.firstname'">First Name</div>
<div>{{ 'member.firstname' | translate }}</div>

Somewhere in my application, I have a button to switch the language to english, which calls

this.translateService.use('en');

When I click the button, the pipe does its thing, but the directive does not.

_Presumable cause_

When checking translate.directive.ts, I noticed that the node.lastKey is always equal to key, and that's why the translation does not occur.

updateValue(key: string, node: any, translations: any) {
        if(key) {
            let interpolateParams: Object = this.translateParams;
            if(node.lastKey === key && this.lastParams === interpolateParams) {
                return;
            }

When I comment it out (the check "if (node.lastKey ..."), the translation does occur and it works fine.
The if statement is probably there for a reason, but I guess that the fact the language changed should be added to the check as well.

I use version of g2-translate, and version 2.3.1 of angular.

Could you please have a look at this?

Thanks,
Jeroen.

  1. Create a shared module

import { NgModule } from '@angular/core';
import { HttpModule, Http } from '@angular/http';
import { CommonModule } from '@angular/common';
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClientModule, HttpClient } from '@angular/common/http';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
}

@NgModule({
imports: [
HttpModule,
CommonModule,
HttpClientModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
isolate: false
})
],
exports: [
HttpModule,
CommonModule,
HttpClientModule,
TranslateModule
]
})
export class SharedModule {

 constructor(private translate: TranslateService) {

    translate.addLangs(["en", "es"]);
    translate.setDefaultLang('en');

    let browserLang = translate.getBrowserLang();
    translate.use(browserLang.match(/en|es/) ? browserLang : 'en');
}

switchLanguage(lang) {
  this.translate.use(lang);
}

}

  1. Include this module in every page module.ts you are going to use translate

  2. Add this code to your app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { ActionSheet } from '@ionic-native/action-sheet/ngx';

import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { SharedModule } from './sharedmodule';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}

@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
SharedModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
isolate: false
})

],
providers: [
StatusBar,
SplashScreen,
ActionSheet,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}

As everyone I have a same issue where the translations are getting updated with translate pipe but not with other methods like .instant() or .get();
The only work around seems to be working is below

this.prop = translateService.instant('MY_TRANSLATE_KEY');
this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
     // do something
     this.prop = event.translations['MY_TRANSLATE_KEY']; // setting this again 
});

Is this solved or can anyone suggest better workaround here?

Same Issue here, When I change language, texts translated by pipes are changed, but not texts translated by directive... Can anybody help?

Was this page helpful?
0 / 5 - 0 ratings