1

I have a navigation bar, there have multiple languages, in the app.component

constructor(public translate: TranslateService) {
    translate.addLangs(['en', 'fr']);
    translate.setDefaultLang('en');

    const browserLang = translate.getBrowserLang();
    translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');

  }

and i have another home component, in the ngOnInit i have a table , table header is dynamic.

not working

ngOnInit() {
  this.cols = [

        { field: 'productID', header: this.translateService.instant('productID') },
    }

But it is working well in button click:

buttonClicked(){

 this.cols = [

            { field: 'productID', header: this.translateService.instant('productID') },
        }

console.log(this.translateService.instant('productID'));

}

another solution I have found is to do the below subscribe method in each component and get the translated value which key needs to translate

constructor( private translateService:TranslateService) {

      this.translateService.use('fr');


    this.translateService.get(
      ['productID',],

      )
      .subscribe(val => {
      console.log( val['productID']);

      });

     }

sample : looking for better solution https://stackblitz.com/edit/ngx-translate-example-h6uypw?file=src/app/home/home.component.ts

Mohamed Sahir
  • 2,482
  • 8
  • 40
  • 71

2 Answers2

2

You are calling instant method. It's possible that translations are not yet loaded when you call it. You could try to use something like translate.get('test') . Then subscribe and wait when translations are loaded and then use instant ().

You can also use translate pipe rather than translate service

<h3>{{ "HOME.Description" | translate}} </h3>

If you want to continue using the translateService and not use Pipe, then you need to add translateservice in APP_INITIALIZERS in app_module. When we do this, it will initialize translateService before initializing your component and hence .instant() function will work. The code for app.module.ts is as follows(according to the code published on the stackblitz url):

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppComponent } from './app.component';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {TranslateModule, TranslateLoader, TranslateService} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import { HomeComponent } from './home/home.component';
import {MultiTranslateHttpLoader} from 'ngx-translate-multi-http-loader';

// AoT requires an exported function for factories
export function HttpLoaderFactory(httpClient: HttpClient) {
  return new TranslateHttpLoader(httpClient);

  //return new TranslateHttpLoader(httpClient, 
    //environment.feServerUrl + '/assets/i18n/', '.json'); 
}
export function translateFactory(translate: TranslateService) {
  return async () => { 
                translate.setDefaultLang('en-US');
        translate.use('en-US');
        return new Promise(resolve => {
            translate.onLangChange.subscribe(() => {
                resolve();
            });
        });
    };
}

@NgModule({
  declarations: [
    AppComponent,HomeComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: translateFactory,
      deps: [TranslateService],
      multi: true
    },
  ],
  bootstrap: [AppComponent]
})

export class AppModule {

}

Drashti Dobariya
  • 2,455
  • 2
  • 10
  • 23
  • I have 24 columns in a table header i need to add each value in the subscribe `this.translateService.get(['productID','productName',.......etc ,]).subscribe(val => { console.log( val['productID']); }); }' – Mohamed Sahir Apr 29 '20 at 12:03
  • https://stackblitz.com/edit/ngx-translate-example-h6uypw?file=src/app/home/home.component.ts I have added a stackblitz , instead of getting every column key inside subscribe, is there any other ways. in my qn i have added a solution that is match to ur solution, i need alternate ways – Mohamed Sahir Apr 29 '20 at 14:38
  • I saw your code on stackblitz. Rather than using the translate service in component, why don't you use translate pipe in html. ```

    {{ 'HOME.Description' | translate}}

    ```
    – Drashti Dobariya Apr 29 '20 at 14:53
  • sorry that is an example case for understanding , In my case there are 50 dynamic columns names are in the grid , which is coming from server response, so I need to translate all the column names which I declare in the components.i don't have an option to put it in html – Mohamed Sahir Apr 29 '20 at 15:04
  • `this.productSrevice.getProduct().subscribe(response => { this.cols = [ { field: 'response.data.productId', header: this.translateService.instant('Home.productID')}, { field: 'response.data.productName', header: this.translateService.instant('Home.productName') }, etc ]; console.log(this.translateService.instant('Home.productID')); }` – Mohamed Sahir Apr 29 '20 at 15:10
  • I have updated the solution to use the translateService inside the APP_INITIALIZERs. The solution is tested on the stackblitz and it is working. I hope this helps. – Drashti Dobariya Apr 30 '20 at 13:03
  • @DRASHTIDOBARIYA - can you share the stackblitz url where you have updated the fix. – krrr25 Jul 06 '20 at 06:09
0

do you have init the translation TranslateModule in your app.module.ts:

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

import { AppComponent } from './app.component';

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

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,

        // ngx-translate and the loader module
        HttpClientModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient]
            }
        })
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

// required for AOT compilation
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

In Component you can use it:

import {Component} from '@angular/core';
import {TranslateService} from '@ngx-translate/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent {
    constructor(private translate: TranslateService) {
        translate.setDefaultLang('en');
    }
}

Additional: In the constructor your translations probably haven't been loaded yet.

Use another life cycle hook like

ngAfterContentInit()

Micha
  • 906
  • 6
  • 9
  • yes i did, the problem here it is working well in pipe translate in HTML , when using instant it is working well in button click problem is ngOnint , constructor it is not working – Mohamed Sahir Apr 29 '20 at 12:07
  • add one more component and translate form contsructor – Mohamed Sahir Apr 29 '20 at 12:08
  • the declaration in contructor() should work if used correct! You can use ngAfterContentInit() instead of ngOnInit() – Micha Apr 29 '20 at 12:16
  • not working see the stackblitz https://stackblitz.com/edit/ngx-translate-example-h6uypw?file=src/app/home/home.component.ts – Mohamed Sahir Apr 29 '20 at 12:46