'NGX translate custom loader not getting called if we select the same language
I am using ngx translate with Angular 9. Here are my dependencies:
@angular/cli": "^9.0.1"
@ngx-translate/core": "^12.1.2",
@ngx-translate/http-loader": "^5.0.0"
I have a child lazy-loaded module (Home module) which contains a drop-down to select the language. Home module also has an import like this:
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useClass: HomeCustomLoader,
deps: [HttpClient, Store],
},
isolate: false
})
Also, in my App module, I have it like this in my import:
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
defaultLanguage: "en"
})
When I call this.translate.use("en") (same language) from the home-page.component.ts, also part of the home module, it does not call the getTranslation of the custom loader:
export class HomeCustomLoader implements TranslateLoader {
constructor(private http: HttpClient, protected store$: Store<AppState>) {
}
getTranslation(langCountry: string = 'en'): Observable<any> {
....
}
}
However, for a different language this.translate.use("fr") in the home-page.component, it does trigger the getTranslation method.
Is there a way to trigger HomeCustomLoader EVERY time the language changes and not just when a different language is selected? What if the user goes from en -> fr -> en. Or even in the case when the home module loads, I am only able to trigger the getTranslation when I select a different language using translate.use in home-page.component.ts (part of home module).
Solution 1:[1]
Since I have only part of the application code, it is difficult to see the problem clearly. Nevertheless, I have some ideas:
First, take a look at the implementation of the translation service provided by the library: https://github.com/ngx-translate/core/blob/master/projects/ngx-translate/core/src/lib/translate.service.ts
/**
* Changes the lang currently used
*/
public use(lang: string): Observable<any> {
// don't change the language if the language given is already selected
if (lang === this.currentLang) {
return of(this.translations[lang]);
}
let pending = this.retrieveTranslations(lang);
if (typeof pending !== "undefined") {
// on init set the currentLang immediately
if (!this.currentLang) {
this.currentLang = lang;
}
pending.pipe(take(1))
.subscribe((res: any) => {
this.changeLang(lang);
});
return pending;
} else { // we have this language, return an Observable
this.changeLang(lang);
return of(this.translations[lang]);
}
}
As you can see above, if you want to trigger the loading of translations for the current language, it does not work. The translations for the current language have already been loaded and the library takes them from the state of the service.
I suspect that your problem is related to the fact that Angular creates another instance for lazy loaded modules. This is how Angular DI works I recommend you to have a look at https://youtu.be/G8zXugcYd7o where the presenter describes this very well.
You can also read the article about modular translation. It also provides the source code that might be helpful: https://link.ppowstanski.com/modular-translations-stackoverflow
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
