Open iget-master opened 7 years ago
Came across a similar issue in our Anguar 4 project. I eventually mitigated it by wrapping the get()
in setTimeout
with a timeout of 0
Same
I'm running into a similar issue, though wrapping in a setTimeout
didn't solve my problem.
I'm putting all my calls to translate.get('Content.Id')
in an array and passing that to Observable.forkJoin
so that I get all my translations in one call instead of subscribing to get all of them.
The data being emitted by forkJoin
is an array of all my Content.Id
values passed to my get
calls.
Observable.forkJoin([translate.get('Content.Id1'), translates.get('Content.Id2')])
.subscribe(data => console.log(data)); //=> ['Content.Id1', 'Content.Id2'];
Edit ---
I see - you need to put your calls to get
in a setTimeout
, not the subscribe
calls to the Observables that get
returns.
As I'm debugging what's going on inside translate.service.js
I can see in the call to get
this.pending
is false but this.translations
is an empty object, which is caused by the call to get
executing before the call to getTranslation
is made.
Where can I make my calls to this.translate.setDefaultLang('en-US')
and this.translate.use(this.localeId);
so that the translation is loaded into the app before any calls to get
are made?
@sgwatgit In my case, the problem is that I use the translation service inside other services, that was injected on App component, and I configure the translation service default language only on App component's constructor, so the service that depends on it was already loaded and trying to use it.
To solve it, I've extended the translation service and added the configuration to it constructor:
That's my TranslateService
:
import { Inject, Injectable } from '@angular/core';
import { MissingTranslationHandler, TranslateCompiler, TranslateLoader, TranslateParser, TranslateService as NgxTranslateService } from '@ngx-translate/core';
import { TranslateStore } from '@ngx-translate/core/src/translate.store';
import 'rxjs/add/operator/map';
import { AppConfig, appConfig } from '../app/app.config';
@Injectable()
export class TranslateService extends NgxTranslateService {
constructor(
store: TranslateStore,
currentLoader: TranslateLoader,
compiler: TranslateCompiler,
parser: TranslateParser,
missingTranslationHandler: MissingTranslationHandler,
@Inject(appConfig) private appConfig: AppConfig,
) {
super(store, currentLoader, compiler, parser, missingTranslationHandler, true, false);
this.setDefaultLang(this.appConfig.defaultAppLanguage);
this.use(navigator.language);
}
}
Then added this to the providers on my App module:
{provide: NgxTranslateService, useClass: TranslateService},
This replaces the NgxTranslateService
with my own Translate service that extends it with configurations.
@iget-master That's a really nice pattern!
I ended up going a different direction. Since my project is using template i18n directives from @angular and the cli to do .xlf file generation, we have separate builds for each language. I removed all calls to get
and replaced them with instant
.
I then set the translations by importing the json file (via ES module) to my AppModule
and loading them with my own custom loader class. I also set the locale there (in my APP_INITIALIZER
fn) by importing the value from a file.
// AppModule.ts
import { locale } from '../i18n/locale';
import * as translations from '../i18n/runtime-translations.json';
export function appInitializer(
translate: TranslateService) {
return () => new Promise(resolve => {
translate.setDefaultLang('en-US');
translate.use(locale);
// ... other init code
});
}
export class StaticLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
return Observable.of(translations);
}
}
My import of the TranslateModule
looks like this
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: StaticLoader
}
})
I convert my .po
to .json
using a build process so that its available at the above path for each build of the app I perform for each language.
Got this bug, today, any status on this?
☝️
:point_up:
Solved my issue using this.translateService.stream
instead of this.translateService.get
Code:
this.translateService.stream('LOGIN_ERROR').subscribe((value) => {
this.loginErrorString = value;
})
this might also help others: this.translateService.instant('LOGIN_ERROR')
Solved my issue using
this.translateService.stream
instead ofthis.translateService.get
Code:
this.translateService.stream('LOGIN_ERROR').subscribe((value) => { this.loginErrorString = value; })
this might also help others:
this.translateService.instant('LOGIN_ERROR')
What about this issue with memory leak? #727
Dirty workaround:
translate(key: string): Promise<string> {
const message$ = defer(async () => this.translateService.instant(key));
return message$
.pipe(
delay(10),
expand(value => value !== key ? EMPTY : message$),
filter(value => value !== key)
)
.toPromise();
}
I'm submitting a ... (check one with "x")
Current behavior this.translateService.get('MY.KEY.NAME').subscribe(console.log); // Console logs: "MY.KEY.NAME" instead of "The translated key value"
Expected/desired behavior
Since it's an observable, the expected result is that the service wait for the translations load before resolving the promise.
Reproduction of the problem
I'm using it on Ionic 3, so I have to override the loader to make things work. I'm overriding it with this:
Module import:
The loader:
Then try to use
translateService.get()
on the very first line of code you have, like App component's constructor.Please tell us about your environment:
ngx-translate version: 7.2.0
Angular version: 4.3.5
Browser: all