core: It can't work normally within lazyload(loadChildren) NgModules

I’m submitting a … (check one with “x”)

[ ] bug report => check the FAQ and search github for a similar issue or PR before submitting
[x] support request => check the FAQ and search github for a similar issue before submitting
[ ] feature request

Current behavior when I use lazyload(loadChildren) route, it’s not easy to subscribe TranslateService change between each NgModules. I create a global translate service to subscribe the change but it fetch ‘*.json’ when each NgModule loaded.

Expected/desired behavior It can auto change the language within NgModules

Please tell us about your environment:

  • ng2-translate version: 2.4.3
  • Angular version: 2.0.0-rc.6
  • Browser: [all]
  • Language: [TypeScript 2.0-rc]

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 29 (3 by maintainers)

Most upvoted comments

Ok I just checked the problem, this is what I did:

  • import TranslateModule into my SharedModule
  • prepare the translation in my SharedModule:
@NgModule({
    imports: [
        ...MODULES,
        TranslateModule.forRoot({
            provide: TranslateLoader,
            useFactory: (http: Http) => new TranslateLocalStorageLoader(http, 'assets/i18n', '.json?t=' + (new Date().getTime())),
            deps: [Http]
        })
    ],
    declarations: [
        ...COMPONENTS,
        ...DIRECTIVES,
        ...PIPES
    ],
    providers: [
        ...PROVIDED_SERVICES
    ],
    exports: [
        ...COMPONENTS,
        ...DIRECTIVES,
        ...PIPES,

        // modules
        ...MODULES,
        TranslateModule
    ]
})
export class SharedModule {
    constructor(translate: TranslateService) {
        // get the current UserLang
        userLang = translate.getBrowserLang();

        // 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(userLang);
    }
}

And voilà ! It works in all my lazy loaded modules, as long as they import the SharedModule

Ok, static instances it is then, thanks for the info

I’m not sure about that. I think the correct behaviour was already proposed here https://github.com/ocombe/ng2-translate/issues/209 We just have to configure TranslationModule with forRoot call in AppModule and then import and re-export it in SharedModule. This solution seems to work for me, strings are translated in both main and lazy modules and resource bundles are not loaded more than once

ok, I still have a trick in my sleeve if I cannot find a way to fix this, I can make the translations and currentLang static so that you can have multiple instances but they keep the same “state”, but it means that it won’t be possible to have different instances of the service in different states (I don’t think it’s a good idea, but there may be some use cases).

I will try to fix it this week end, but I don’t know if I’ll have the time (because I need to prepare myself for angular connect next week).

@neolanders Thanks. Can you take a look at my project and see what I might be doing wrong? It is based on JHipster and so the language services are provided by way of JhiLanguageService in the ng-jhipster library which uses a JhiConfigService to configure ngx-translate without my needing to import and configure the TranslateModule in my app.module. So when I add TranslateModule.forRoot(...) to imports of AppModule, everything breaks and I just see “translation not found…” messages everywhere.

I don’t know how to make my lazy-loaded pages use the same translation instances as the eager-loaded part of the app so that changing the language in an eager component of the nav bar affects the language used by the lazy-loaded pages.

I have also tried this idea but I think it suffers from the same problem that I don’t know how to control ngx-translate configuration in a JHipster app. This is probably more a JHipster question but maybe you have some ideas. I’m asking in different places. Such is life when using open source software.

Well, first of all, thanks for having a look at this, but I noticed this does not completely fix the problem.

What it does fix is that no strings will be translated at all. What it doesn’t fix is changing the language (using translate.use(...)) by calling that method in a non-lazy-loaded module won’t translate / update any strings in the lazy-loaded module.

EDIT: it works, if you only have one TranslateService used by making the translate property in your SharedModule static. But that is no good option (considering unit testing for example, and it leads to tight coupling).

export class SharedModule {
    public static translate;
    constructor(translate: TranslateService) {
        SharedModule.translate = translate;
        // ...code from above
    }
}
export class NavbarComponent {
    private switchLang(lang: string): void {
        // this.translate.use(lang);
        SharedModule.translate.use(lang);
    }
}

Could you please have a look at this again? Thank you.