ngx-translate language change is not effect throughout application
Asked Answered
A

1

5

I have created the application with the pages like dashboard and settings. Now I want to change the language throughout the application when I change the language option. But it is working only for the settings page where I have called the language change function not in dashboard page.

Experts inputs please?

settings.ts

import { Component, OnInit } from '@angular/core';
import { TranslateService, LangChangeEvent } from '@ngx-translate/core'

@Component({
  selector: 'app-settings',
  templateUrl: './settings.component.html',
  styleUrls: ['./settings.component.scss']
})
export class SettingsComponent implements OnInit {

  public lang: string;
  constructor(private translate: TranslateService) {
    this.lang = "en";

    translate.setDefaultLang('en');

    let last = localStorage.getItem("selectedLang");
    // the lang to use, if the lang isn't available, it will use the current loader to get them
    translate.use(last);
  }


  changeLanguage(value: string) {

    console.log(value);
    if (value == "German") {
      this.lang = "de";
      localStorage.setItem("selectedLang", this.lang);
      this.translate.use(this.lang);
    }

    if (value == "English") {
      this.lang = "en";
      localStorage.setItem("selectedLang", this.lang);
      this.translate.use(this.lang);
    }
  }
}

settings html

<div class="form-group">
  <label [innerHTML]="'description' | translate"></label>
  <p>Language for user interface and display data.</p>
</div>

dashboard html

<div class="card card-small dash-warning">
      <h2>
        <i class="cis2-fa cis2-fa-dg-logo"></i>
      </h2>
      <span class="m-t-20" [innerHTML]="'dash.doc_gen_status' | translate"></span>
      <h2 class="upper-case bold" [innerHTML]="'dash.doc_gen_unavail' | translate">Unavailable</h2>
    </div>

app.module.ts

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

@NgModule({
  imports: [BrowserModule, BrowserAnimationsModule, AppRoutingModule, HttpClientModule, ReactiveFormsModule, ToasterModule.forRoot(), NgDynamicBreadcrumbModule, TooltipModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (createTranslateLoader),
        deps: [HttpClient]
    }
  })],
  declarations: [AppComponent, DashboardComponent, HeaderComponent, SidebarComponent, LoginComponent],
  providers: [LoggerService, DataService, Title, ToasterService, { provide: APP_BASE_HREF, useValue: '/' }, Resolver, httpInterceptorProviders],
  bootstrap: [AppComponent]
})

app.routing.module.ts

const routes: Routes = [
  {
    path: routePaths.login,
    component: LoginComponent
  },
  {
    path: routePaths.dashboard,
    component: DashboardComponent,
  },
  {
    path: routePaths.userProfile,
    loadChildren: './modules/userProfile/user-profile.module#UserProfileModule'
  },
  { path: '**', redirectTo: routePaths.login, pathMatch: 'full' }
];

user.profile.module.ts

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

@NgModule({
  imports: [CommonModule, ReactiveFormsModule, FormsModule, UserProfileRoutingModule,
    AgGridModule.withComponents([]), TooltipModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (createTranslateLoader),
        deps: [HttpClient]
    }
  })],
  declarations: [SettingsComponent],
  providers: [{ provide: APP_BASE_HREF, useValue: '/' }]
})
export class UserProfileModule { }
Avocation answered 1/7, 2019 at 7:51 Comment(2)
Is SettingsComponent part of a lazy loaded module? I think you have two TranslateService, one for global and one for lazy loaded module in which SettingsComponent is declared. Can you share your module setup?Qianaqibla
yes, it is lazy loaded module and declared two places. What would be the correct approach to make it work throughout the app from one place change.Avocation
Q
22

It's because you import TranslateModule.forRoot in multiple places which makes lazy loaded modules have their own instances of TranslateService.

What you should do is to keep TranslateModule.forRoot in AppModule only and any other module who needs TranslatePipe will just import TranslateModule.

TranslateService will be globally available to all modules and it will be singleton. So, change UserProfileModule to this

@NgModule({
  imports: [CommonModule, ReactiveFormsModule, FormsModule, UserProfileRoutingModule,
    AgGridModule.withComponents([]), TooltipModule,
    TranslateModule],
  declarations: [SettingsComponent],
  providers: [{ provide: APP_BASE_HREF, useValue: '/' }]
})
export class UserProfileModule { }
Qianaqibla answered 1/7, 2019 at 8:34 Comment(6)
@Avocation also one more thing, APP_BASE_HREF should be defined in root module as well. Why do you redefine it within lazy modules?Qianaqibla
By mistake defined, I will consider it. Thanks a lot.Avocation
full documentationUrbanna
I am also having a component which is using a component defined in different library. It is not updating.Herthahertz
@SMIftakhairul glad to be able to help :)Qianaqibla
Oh man you saved my day. The ngx-translate documentation hella confusing. :)Implicit

© 2022 - 2024 — McMap. All rights reserved.