Core: Angular 7: Translate service in component does not work, but in HTML works fine

Created on 10 Apr 2019  路  8Comments  路  Source: ngx-translate/core

Current behavior

In my project, I load the TranslateModule as follows:

app.module.ts

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

@NgModule({
...
imports: [
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }),
...

app.component.ts

  constructor(
    private translate: TranslateService,
    private store: Store<AppState>
  ) {
    translate.setDefaultLang('en');
    translate.use('en');
  }

In the web pages for the app components, translates work correctly. But, in the component Typescript code the translate service returns the key and not the translate. For example:

const filter = this.translate.instant('toolbar.action-filter-options.all-actions');

Expected behavior

Expecting the method call to return the translation for the string.

How do you think that we should fix this?

If this is a user error, I'm not sure what it could be. I use @ngx-translate in another project and it works correctly there.

Minimal reproduction of the problem with instructions

Environment


ngx-translate version: 11.0.1 
Angular version: 7.2.0


Browser:
- [X] Chrome (desktop) version  73.0.3683.86
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX

For Tooling issues:
- Node version: v10.15.0
- Platform: Mac

Others:

Most helpful comment

@mcpierce
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 ().

All 8 comments

Additionally. I set a breakpoint in the app.component.ts component's constructor, just after the translate service is injected and the language loaded, and tried doing the translation and see the same behavior; i.e., it returns the key and not the translation.

Doing some more work, it seems the translation service does not have the translation itself loaded. I added a missingTranslationHandler in app.module.ts:

export class TranslateHandler implements MissingTranslationHandler {
  private response: String;

  handle(params: MissingTranslationHandlerParams) {
    console.log('*** Missing text for:', params.key);
    return 'some translated text'; // here u can return translation
  }
}

...
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate: true,
      missingTranslationHandler: [{ provide: MissingTranslationHandler, useClass: TranslateHandler }]
    }),
...

and I'm seeing that ALL of those pieces to be translated from within the component aren't found: I see the MissingTranslationHandler being called for all of them. But I can put those same keys into the HTML and they're translated just fine.

Hoping I can add some additional insight as I have just run into a similar issue, when trying to retrieve a translated string in a component, specifically in Chrome. All HTML translations work fine, and even other translate.get methods work fine depending where they are called. The failures that we are seeing are within a component's ngOnInit lifecycle hook. The translation works fine in FF but not in Chrome. We have also discovered that it appears to be related to the en.json file size or number of key/value pairs. If I delete several key/value pairs from en.json up to a certain point then the translation will start to work. I can confirm that it is not specific to the keys that I am deleting, but specific to the number of keys that I am deleting. I have tried several combinations to reproduce. @mcpierce , if you do not have a similar result I can remove this comment and open a new bug so that I don't muddy the issue you have found.

@miclettej

I tried loading the page in Firefox and see the same behavior; i.e., lack of translation appearing.

I then tried removing everything from en.json, so it would be just the entries for this one component, and that had no effect either.

So, unfortunately, I don't think what you suggested helped.

One more comment: I added buttons to change languages, and wrapped the component code that does the translation inside of an onLangChange handler. That's the only time that I see things translated.

So is it the case that the translation isn't being loaded in AppComponent and only getting loaded when I force the language to change? If so, what should I do to debug that?

@mcpierce
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 ().

@mcpierce
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 ().

I think that's the case, which is strange since on another project doing the same works consistently. But on this project I have the code waiting for a language change before generating the text and it works now.

Had the same situation, spent hours debugging until found this @Ferrzo's note on async loading (thanks man!). I was sure it's covered somehow by .instant() implementation... And yes, as for @mcpierce, it works sporadically for me as well - sometimes without waiting for the subscription result, sometimes only inside of it. That should be added to docs in some way.

Was this page helpful?
0 / 5 - 0 ratings