Issue with i18n (ngx/ng2 translate)

I have an issue with ngx or ng2 translate (at that point I’ll take anything that works).
I’m trying to implement a translation in my app, but I keep getting this message:
The pipe 'translate' could not be found
I feel like I’ve tried everything. My app.module.ts:

import { HttpClient } from '@angular/common/http';
import {ErrorHandler, LOCALE_ID, NgModule} from '@angular/core';
import {IonicApp, IonicErrorHandler, IonicModule} from 'ionic-angular';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {BrowserModule} from '@angular/platform-browser';

import {MyApp} from './app.component';
import {AuthProvider} from '../providers/auth/auth.provider';
import {Camera} from '@ionic-native/camera';
import {HttpModule} from '@angular/http';
import {SunMoonProvider} from '../providers/sun-moon/sun-moon.provider';

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

@NgModule({
  declarations: [
    MyApp,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpModule,
    IonicModule.forRoot(MyApp, {
      tabsHideOnSubPages: true
    }),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (createTranslateLoader),
        deps: [HttpClient]
      }
    }),
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    {provide: LOCALE_ID, useValue: "en-GB"},
    BLE,
    SunMoonProvider,
  ]
})
export class AppModule {
}

My page.ts:

import { TranslateService } from '@ngx-translate/core';
import {AfterViewInit, Component, Input} from '@angular/core';
import {NavController, NavParams} from 'ionic-angular';

@Component({
  selector: 'article-thumbnail',
  templateUrl: 'article-thumbnail.html'
})
export class ArticleThumbnailComponent implements AfterViewInit {
  @Input() article: any;

  constructor(public navCtrl: NavController, public navParams: NavParams, translate:TranslateService) {
    translate.use('en_GB');
  }

  ngAfterViewInit() {
  }

  goToArticle() {
    this.navCtrl.push('ArticlePage', {article: this.article});
  }
}

My page’s HTML:

<div tappable (click)="goToArticle()">
  <img class="more" src="./assets/icon/more.png">
  <ion-grid>
    <ion-row align-items-center>
      <ion-col col-12 align-self-center>
        <h1 class="category">{{article.category}}</h1>
        <h1 class="title">{{article.title}}</h1>
        <h1 class="title">{{'HELLO' | translate}}</h1>
      </ion-col>
    </ion-row>
  </ion-grid>
</div>

Where are you using the translate pipe ? Can’t see it in the HTML

Quite right! I just updated the template

Do you have modules with your pages you’re using?
If so, you’ll have to import the TranslateService for each page module

In your page.module.ts add the following:

import { TranslateModule } from "@ngx-translate/core";

@NgModule({
...
  imports: [
    ....
    TranslateModule,
    ....
  ],
...

I don’t have modules in the pages, I managed to make the error go away by importing the translatemodule to my component.module.ts, but now it only returns the key I put in the HTML, as if the pipe wasn’t there

Where did you get the component.module.ts from then? Could you describe your folder structure pls?
It should be something like this:

src
 |- app
  |- app.component.ts
  |- app.html
  |- app.module.ts
  |- app.scss
  |- main.ts
 |- assets
   |- i18n 
     |- en_GB.json
 |- pages
   |- page
     |- page.html
     |- page.scss
     |- page.ts

Ok my bad, I do have modules;
My component module looks like this:

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { RealtimePage } from './realtime';
import { ComponentsModule } from '../../components/components.module';
import { TranslateModule } from '@ngx-translate/core';

@NgModule({
  declarations: [
    RealtimePage,
  ],
  imports: [
    IonicPageModule.forChild(RealtimePage),
    TranslateModule,
    ComponentsModule
  ],
})
export class RealtimePageModule {}

Okay,
Then, as said, you have to import the TranslateModule in your page.module.ts (as in EVERY page you’re lazy loading )
The components.module which you’re using would need that import too.

Alright I’ve done all this, but when I tried to do a console.log(JSON.stringify(Translate.use(en_GB))), all that returns to the console is

console.log: {"_isScalar":true,"scheduler":null}

Which I think means my json file is not being fetched properly or at all.

Try TranslateModule.forChild() instead of just TranslateModule in your lazy loaded components/modules/pages/etc.

p.s.: If that could help, in this simple lazy loaded project I loaded ngx-translate, you could have a look https://github.com/peterpeterparker/ionic-zurich-introduction-demo

translate.use() returns an observable. Not returning the text en_GB is expected. Try the ‘currentLang’ property


constructor (public translate:TranslateService){
}

myFunction(){
    console.log(this.translate.currentLang);
}

Btw. You can also check in your chrome developer tools (F12) if the translation file is loaded.
Go to the network tab and filter for 'assets’
There you should see your ‘en_GB.json’ and the status of it.

The function doesn’t get my json file; everything is in place to properly retrieve the translation, the app doesn’t throw any errors, any function from translate service works, but I can’t link the json file. Any idea?

Hoi?
maybe translatemodule is defect.

  • Is your translate.use(...) located in app.component.ts or in another class ? If another class, could you try move it there

  • Could you try renaming and using a file en.json instead of en_GB.json (just in case)

  • Is your project on Github? Could I clone it to try/have a look?

I deleted my changes and I put exactly what you did (except for the switcher) and still what appears is the key. I changed my .json files into ‘simpler’ names (‘en’ and ‘fr’).

I put the translate.use(...) in the app.component as per your advice. Btw hardcoding the translations in the ts file works, so it definitely seems like a .json linking issue.

Unfortunately I can not sent you the files, as this is a work project and I’m not too allowed to share it.

Did you also renamed TranslateModule with TranslateModule.forChild() in your lazy loaded modules?

1 Like

I actually did yes, here’s my lazy loaded module’s code:

import { IonicPageModule } from 'ionic-angular';
import { RealtimePage } from './realtime';
import {ComponentsModule} from '../../components/components.module';

import {TranslateModule} from '@ngx-translate/core';


@NgModule({
  declarations: [
    RealtimePage,
  ],
  imports: [
    IonicPageModule.forChild(RealtimePage),
    TranslateModule.forChild(),
    ComponentsModule
  ],
})
export class RealtimePageModule {}

Thanks for your help so far by the way!

No worries…weird it should work. I mean I use ngx-translate in many projects, always worked so far

in your app.component.ts:

  • Could you try to set a default language too? For example this.translate.setDefaultLang('en');

  • When you printout the currentLang, does it work this.translate.currentLang

  • If you try to translate a key of your json, like this.translate.instant('YOUR_KEY') is something correctly found?

  • Which version of @ngx-translate/core and @ngx-translate/http-loader are you using?

I am using the latest versions of both:

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

When I print this.translate.instant('KEY') I just get the key.
When I print the currentLang after setting it up as either translate.use of translate.setDefaultLang, i do get the currentLang.

Here my function for getting json files:

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

And here is my structure:
src
–|app
----|app.component.ts
----|app.html
----|app.scss
----|main.ts
–|assets
----|i18n
------|en.json
------|fr.json
–|pages
----realtime
------|realtime.html
------|realtime.module.ts
------|realtime.scss
------|realtime.ts

I think I just saw something not correct…you are using HttpClient but you are loading HttpModule which should actually be HttpClientModule. Could you try to replace that and try again? (in app.module.ts)

HttpModule -> Http -> Decrepated
HttpClientModule -> HttpClient