Search code examples
angulartypescriptngx-translate

ngx translate - Using get or instant method in ts file is not working


I'm using a sharedModule that imports into other modules, so I'm trying to use ngx-translate on all files. In app.component.ts the get method works well but in test.component.ts not. And the strange thing is that the pipe ( | translate ) in html files works well. Like the thread executes this.translateService.use(lang); in app.component.ts stops and goes to this.translate.get('testTranslation') of the test.component.ts, fails and then comes back to app.component.ts and it works. At the moment, my code looks something like this:

My structure:

-> src -> app.module.ts
       -> app.component.ts

       -> shared/shared.module.ts

       -> test/test.module.ts
              /test.component.ts

app.module.ts

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { SharedModule } from '../shared/shared.module';
import { TestModule } from '../test/test.module';

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

@NgModule({
declarations: [ *(some component)* ],
imports: [ 
    *(other modules)*, 
    SharedModule, 
    TestModule,
    TranslateModule.forRoot({
        loader: {
            provide: TranslateLoader,
            useFactory: (createTranslateLoader),
            deps: [HttpClient]
        },
    }) 
],
})
export class AppModule { }

app.component.ts

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

constructor() {
    const lang = window.navigator.language;
    try {
      this.translateService.setDefaultLang(lang);
      this.translateService.use(lang);
      this.translate.get('testTranslation').subscribe((res: string[]) => { // instant doesn't work too
      console.log(res); // expected: 'Translation Works'
                        // result: 'Translation Works'
    } catch (e) {
        console.log('Language file is not found: ' + lang, e);
    }
}

shared.module.ts

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: [ *(some component)* ],
imports: [ 
    *(other modules)*, 
    SharedModule, 
    TranslateModule.forChild({
        loader: {
            provide: TranslateLoader,
            useFactory: (createTranslateLoader),
            deps: [HttpClient]
        },
    }) 
],
exports: [
    TranslateModule
],
})
export class SharedModule { }

test.module.ts

import { SharedModule } from '../shared/shared.module';

@NgModule({
declarations: [ 
    *(some component)* 
],
imports: [ 
    *(other modules)*, 
    SharedModule, 
],
})
export class SharedModule { }

test.component.ts

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

  constructor(private translate: TranslateService) {
  }

  ngOnInit(): void {
    this.translate.get('testTranslation').subscribe((res: string[]) => { // instant doesn't work too
      console.log(res); // expected: 'Translation Works'
                        // result: 'testTranslation'
    });

I've tried a few things but none works.


Solution

  • in app.module.ts try:

    import {APP_INITIALIZER, Injector, NgModule} from '@angular/core';
    import {LOCATION_INITIALIZED} from '@angular/common';
    @NgModule({
        ...,
        providers: [
            ...,
            {
                provide: APP_INITIALIZER,
                useFactory: appInitializerFactory,
                deps: [TranslateService, Injector],
                multi: true
            }
        ]
    })
    export class AppModule {}
    
    // tslint:disable-next-line:no-any
    export  function appInitializerFactory(translateService: TranslateService, injector: Injector): () => Promise<any> {
      // tslint:disable-next-line:no-any
      return () => new Promise<any>((resolve: any) => {
        const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
        locationInitialized.then(() => {
          translateService.use(window.navigator.language)
            .pipe(take(1))
            .subscribe(() => {},
            err => console.error(err), () => resolve(null));
        });
      });
    }