Romanchuk / angular-i18next

angular v10+ integration with i18next v19.4+
MIT License
131 stars 33 forks source link

changeLanguage not working in ionic(angular) 4 #40

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hi here is what I do..

my app module

...

import { I18NextModule, ITranslationService, I18NEXT_SERVICE, I18NextLoadResult, defaultInterpolationFormat } from 'angular-i18next';
import { NgModule, APP_INITIALIZER, LOCALE_ID } from '@angular/core';
import XHR from 'i18next-xhr-backend';
import * as i18nextLanguageDetector from 'i18next-browser-languagedetector';

/*
 * Platform and Environment providers/directives/pipes
 */
const i18nextOptions = {
  lng: 'fr',
  whitelist: ['en', 'fr'],
  fallbackLng: 'en',
  debug: true, // set debug?
  returnEmptyString: false,
  ns: [
    'translation',
    'validation',
    'error'
  ],
  interpolation: {
    format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
  },
  // backend plugin options
  backend: {
    loadPath: 'assets/locales/{{lng}}/{{lng}}.{{ns}}.json'
  },
  // lang detection plugin options
};

export function appInit(i18next: ITranslationService) {
  return () => {
    const promise: Promise<I18NextLoadResult> = i18next
      .use(XHR)
      .use(i18nextLanguageDetector)
      .init(i18nextOptions);
    return promise;
  };
}

export function localeIdFactory(i18next: ITranslationService)  {
  return i18next.language;
}

export const I18N_PROVIDERS = [
  {
    provide: APP_INITIALIZER,
    useFactory: appInit,
    deps: [I18NEXT_SERVICE],
    multi: true
  },
  {
    provide: LOCALE_ID,
    deps: [I18NEXT_SERVICE],
    useFactory: localeIdFactory
  },
];

firebase.initializeApp(environment.firebaseConfig);

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    IonicStorageModule.forRoot(),
    I18NextModule.forRoot(),
    AppRoutingModule,
    VirtualScrollerModule,
    FormsModule,
    ReactiveFormsModule,
    ComponentsModule,
  ],
  providers: [
    StatusBar,
    GooglePlus,
    SplashScreen,
    Camera,
    AppRate,
    Contacts,
    SocialSharing,
    Facebook,
    AppAvailability,
    I18N_PROVIDERS,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

IN my profile page I change language using i18next service my this...

selectLanguage(event) {
    i18next.changeLanguage(event.target.value, (err, t) => {
      console.log('err', t);
    })

  }

but when my drop down select the value language is not changing.. when I come back to profile page its changes.. but on home page its same .. so what's the problem is ??

I have used lazy load and in each module I have added I18NextModule.forRoot(), in providers.

please help :)

ghost commented 4 years ago

@Romanchuk can you please give you insights ? :)

Romanchuk commented 4 years ago

@koza-tavisca my guess: it happends because of i18nextPipe is pure pipe. Language changed but for pipe input key stayed the same, so it won't trigger recalc of the pipe. Simpliest option to solve it - is to reload page.

Also i want to return to idea to implement alternative impure i18next pipe

Here you can see story and reasons behind why pipe is pure: https://github.com/Romanchuk/angular-i18next/issues/35

ghost commented 4 years ago

I see.. thanks for pointing this out.. any work around for now untill you make the changes ? I really needed this

Romanchuk commented 4 years ago

@koza-tavisca Here is an implementation in the demo app: https://github.com/Romanchuk/angular-i18next-demo/blob/13180dacea142959ff892c727f54701d6f483f99/src/app/structure/header-controls/header.language.component.ts

Romanchuk commented 4 years ago

Just reload page

ghost commented 4 years ago

Yeah got one work around but reloading page is not the best practice for mobile app.so let me know if you have any more dynamic solution I have tried my all ways.. out of ideas now..

Thanks :)

Romanchuk commented 4 years ago

@koza-tavisca Hi, i just released version 7.2.0-beta with a new i18nextEager pipe. It is impure pipe so i highly recommend to use it only in combine with OnPush change detection strategy, or else (default change detection) each pipe will retrigger more than one time. You can use it without reloading page. Also this release supports latest i18next version.

ghost commented 4 years ago

OKay buddy let me have a look ...

ghost commented 4 years ago

I have installed the version that you have specified and do following changes on html.

<p> {{ '_profile.label.do_you_provide_any_services' | i18nextEager }}</p>

Still when I change language using following function its now reflecting directly. I need to go back to previous page and need to come back again for changes.

selectLanguage(event) {
    i18next.changeLanguage(event.target.value, (err, t) => {});
 }
Romanchuk commented 4 years ago

@koza-tavisca Its hard to tell. Why don't you change language throught I18nextService that is intergated with angular? You dont need to directly call methods of 18next. Here is example in demo: https://github.com/Romanchuk/angular-i18next-demo/blob/master/src/app/structure/header-controls/header.language.component.ts

i18nextEager pipe works for me and person in related issue: https://github.com/Romanchuk/angular-i18next/issues/35#issuecomment-579183309

Romanchuk commented 4 years ago

@koza-tavisca Hello! Any news?

Romanchuk commented 4 years ago

Closed because of inactivity. Related issue was resolved #35