core
core copied to clipboard
.forChild({}) is not loading anything
Hello.
I'm facing an issue with loading translations. The thing is only main
is loading, but everything else is not.
What I'm doing wrong?
translate.loader.ts
import { TranslateLoader } from '@ngx-translate/core';
import { Observable, from } from 'rxjs';
export class TranslateLoaderFactory {
static forModule(module: string): any {
console.log('module', module); // calls for each feature
return class LazyTranslateLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
console.log('module for ' + lang, module); // calls only for main translations (from AppModule)
return from(import(`assets/i18n/${module}/${lang}.json`));
}
};
}
}
app.module.ts
@NgModule({
imports: [
StoreModule.forRoot({
...
}),
EffectsModule.forRoot([
MainEffects // here's an effect that call: `.setDefaultLang('en')` and `.use('en')`
]),
TranslateModule.forRoot({
extend: true,
isolate: false,
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderFactory.forModule('main'),
deps: [HttpClient],
},
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler,
},
}),
... // other modules
]
})
export class AppModule {}
shared.module.ts
@NgModule({
imports: [TranslateModule], // other modules as well
exports: [TranslateModule], // other modules as well
})
export class SharedModule {}
feature1.module1.ts
@NgModule({
imports: [
TranslateModule.forChild({
extend: true,
isolate: false,
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderFactory.forModule('feature1'),
deps: [HttpClient],
},
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatCompiler,
},
}),
... // other modules
]
})
export class Feature1 {}
Duplicate of #1266 ? This seems to be old problem because we couldn't make forChild
to work correctly when there was a need, so we just went with single json file per project (actually we have 2 files, but loading both on app init).
Also, this library seems to be abandoned as its creator joined Angular team to work on native angular i18n library.
Hello, I did workaround to this problem and using small function it does work as below.
- In lazy loading module,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
extend: true
})
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, './path-to-child-json/', '.json');
}
- in root component of the child module
constructor(
private translate: TranslateService
) {
// Calls when module initialize first time
this.changeLanguage(this.translate.currentLang);
// Calls when user changes language manually
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
this.changeLanguage(event.lang);
});
}
changeLanguage(lang: string) {
if (this.currentLang === lang) {
return;
}
this.currentLang = lang;
this.translate.currentLang = '';
this.translate.use(lang);
}
For lazy-loaded modules with different translation loaders (loading .json
from different files) it seems to be either (in the case of the lazy-loaded):
- (LazyModule
isolate: false
,extend: true
) React to parent module translation events automatically without having to connect anything, just as they say, but cannot load the lazy loaded specific files. - (LazyModule
isolate: true
,extend: true
) We have to propagate changes to parent's translation event changes to the lazy child ourselves, and we can have our specific translations working! But the parent's translation won't work.
It's like I can't blend the two.
I got pretty close though maybe you could have a look and play within StackBlitz
: https://stackblitz.com/edit/translations-and-lazy-loading?file=README.md
@vladkasianenko @docwhite @kunjan343 @liesahead @peterblazejewicz I found the best workaround to make it works with extend: true and isolate: false. The solution is to force the loading of the translation in the constructor of your lazy module: constructor(private translateService: TranslateService) { this.translateService.getTranslation(this.translateService.currentLang); }
I opened a PR to add this to the README doc: https://github.com/ngx-translate/core/pull/1328/files However you will still encounter problem if you want to change lang dynamically without refreshing the page.