I'm using ng2-translate for language handling in an Angular 2 RC5 app I'm creating. The app has two feature modules, one lazy loaded and one eager loaded. TranslateModule is made available through a shared module. The problem is that the translate pipe works fine in the eager-loaded module but not the lazy-loaded one. To verify it has to do with the loading method I converted both to eager-loading and everything worked fine.
A plunk that demonstrates the issue can be found here: Plunker The significant code is below as well.
The initial page is the eager-loaded one, hence why the strings look fine. Click Login and it will go to the lazy-loaded one where all strings are upper-case, i.e. not translated.
Any help would be appreciated.
app.module:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TranslateModule } from 'ng2-translate/ng2-translate';
import { AppComponent } from './app.component';
import { WelcomeModule } from './welcome/welcome.module';
import { routing } from './app.routing';
@NgModule({
imports: [ BrowserModule, WelcomeModule, TranslateModule.forRoot(), routing ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.routing:
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'welcome', pathMatch: 'full'},
{ path: 'backend', loadChildren: 'app/backend/backend.module' }
];
export const routing = RouterModule.forRoot(routes);
app.component:
import { Component } from '@angular/core';
import { TranslateService } from 'ng2-translate/ng2-translate';
@Component({
selector: 'my-app',
template: `
<router-outlet></router-outlet>
`
})
export class AppComponent {
constructor(translate: TranslateService) {
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en');
}
}
shared.module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
import { TranslateModule } from 'ng2-translate/ng2-translate';
@NgModule({
imports: [
CommonModule,
HttpModule,
TranslateModule.forRoot()
],
exports: [
CommonModule,
TranslateModule
],
})
export class SharedModule {}
welcome.module (eager loaded)
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { WelcomeComponent } from './welcome.component';
import { routing } from './welcome.routing';
@NgModule({
imports: [ SharedModule, routing ],
declarations: [ WelcomeComponent ]
})
export class WelcomeModule { }
welcome.component:
import { Component } from '@angular/core';
@Component({
template: `
<h2>{{ 'PLEASELOGIN' | translate }}</h2>
<nav><a routerLink="/backend">{{ 'LOGIN' | translate }}</a></nav>
`
})
export class WelcomeComponent { }
welcome.routing
import { RouterModule } from '@angular/router';
import { WelcomeComponent } from './welcome.component';
export const routing = RouterModule.forChild([
{ path: 'welcome', component: WelcomeComponent}
]);
backend.module (lazy loaded)
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
@NgModule({
imports: [ SharedModule, routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
backend.component:
import { Component } from '@angular/core';
@Component({
template: `
<h2>{{ 'WELCOME' | translate }}</h2>
<nav><a routerLink="/welcome">{{ 'LOGOUT' | translate }}</a></nav>
`
})
export class BackendComponent { }
backend.routing
import { Routes, RouterModule } from '@angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
en.json
{
"LOGIN": "Login",
"LOGOUT": "Logout",
"WELCOME": "Welcome!",
"PLEASELOGIN": "Please Login"
}
In your AppModule call forRoot() In all your lazy loaded modules call forChild() with isolated: true and create a new instance of TranslateHttpLoader with the path to the i18n files for the module. In all your lazy loaded module's main component call use() of TranslateService each time the user changes the language.
To lazy load the component, we will use the import() method inside an async/await function. The above function first clears the container; otherwise, on every click of the button, the new instance of GreetComponent would be added in the container.
Lazy loading is the process of loading components, modules, or other assets of a website as they're required. Since Angular creates a SPA (Single Page Application), all of its components are loaded at once. This means that a lot of unnecessary libraries or modules might be loaded as well.
I had the same problem. Adding TranslateLoader and TranslateService to the forRoot method solved the problem.
import {TranslateModule, TranslateService, TranslateLoader, TranslateStaticLoader} from 'ng2-translate/ng2-translate';
@NgModule({
imports: [..,TranslateModule],
declarations: [..],
exports: [ .., TranslateModule]
})
export class SharedModule {
static forRoot(): ModuleWithProviders {
function translateLoader(http: Http) {
return new TranslateStaticLoader(http, 'i18n', '.json');
}
return {
ngModule: SharedModule,
providers: [UserService, ItemService, {
provide: TranslateLoader,
useFactory: translateLoader,
deps: [Http]
},
TranslateService],
};
}
}
Though the accepted answer pointed me in the right direction, the translator was not working in the lazy loaded module. In other modules it was working.
I had to inject the TranslatorService again in the lazy loaded module's main component and init the language settings like I've done in app.component.ts
export class MainComponentOfLazyLoadedModule implements OnInit {
constructor(private translate: TranslateService) {
Language.currentLang = "en";
translate.addLangs(["en", "sp"]);
translate.setDefaultLang(Language.currentLang);
translate.use(Language.currentLang);
}
ngOnInit() {
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With