Daniel Stephens
Daniel Stephens

Reputation: 3209

How to update the current language with ngx-translate?

I am using Electron 10 and Angular 10 and also use ngx-translate. I would like to update the translations of the current view/page after the user switched the language in a dropdown menu.

During development I use of course Angular with its HTTP server, that's why I use HttpLoaderFactory. But for production builds I use the custom translateFactory which loads the JSON files via TranslateUniversalLoader. Is this ok to do?

Neither in development nor production builds I can make the strings update without restarting the app. I have a dropdown menu and on change I simply call this.translate.use(lang). Is the view supposed to be reloaded? What is the expected behaviour here?

I register the module as follows:

export class TranslateUniversalLoader implements TranslateLoader {
       
  constructor() {
  }

  public getTranslation(lang: string): Observable<any> {
      return of(TRANSLATIONS[lang]);
    }
  }
  
  export function translateFactory() {
    return new TranslateUniversalLoader();
  }
}
...

@NgModule({
  declarations: [AppComponent],
  imports: [
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: isProductionBuild() ? translateFactory : HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate : false
    })

Upvotes: 2

Views: 1719

Answers (1)

polyglot
polyglot

Reputation: 862

I think you are calling this.translate.use(lang) from lazyload-like submodules that are not injected into the root module where TranslateModule is imported. To call it from the lazyload modules, create a service named LanguageService:

@Injectable({ providedIn: 'root' })
export class LanguageService {
   language$ = new BehaviorSubject(null);

   applyLang(lang: string) {
      this.language$.next(lang);
   }
}

And watch language$ change from app.component.ts:

...
export class AppComponent {
   constructor(private languageService: LanguageService, private translate: TranslateService) {
      this.languageService.language$.subscribe(lang => {
          if (lang) {
              this.translate.use(lang); // Use lang here
          }
      });
   }
}

Now you can use LanguageService to change the language from any lazyloaded modules.

...
constructor(private languageService: LanguageService) {}

updateLanguage() {
   this.languageService.applyLang('en'); // Call from components belonging to lazyload modules
}

Otherwise, simplify the flow by calling translate.use from LanguageService directly.

@Injectable({ providedIn: 'root' })
export class LanguageService {
   constructor(private translate: TranslateService) {}

   applyLang(lang: string) {
      this.translate.use(lang);
   }
}

Upvotes: 2

Related Questions