I18next loading after page renders


#1

I’m using the i18next library in my ionic2 application. I’ve ad some difficulty getting any of the actual plugins working with any sort of success but using the lib directly works, sort of.

When the application loads, I call the below function, which runs asynchronously

 i18next.use(i18nextXHRBackend).init({
      debug: true,
      lng: 'en',
      fallbackLng: 'en',
      returnEmptyString: true,
      // initImmediate : false,
      defaultNS: 'static',
      ns: ['static', 'dynamic'],
      // mapping: { "specific_backend_message": "message_for_translate" },
      backend: {
        loadPath: AppService.TRANSLATIONS_URI
      },
      interpolation: {
        prefix: "{{",
        suffix: "}}"
      }
    });

As its async the application continues to load and as a result the translations don’t load as this process isn’t completed. The view is then rendered before the translations are loaded and so don’t show correctly. How do I prevent the root view getting rendered until this process completes? I’ve added the full app.component.ts below

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform, ModalController, Loading, LoadingController, AlertController, Events } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Storage } from '@ionic/storage';

import { PropertyListPage, RoomAvailabilityPage, DashboardPage, LoginPage } from '../pages/pages';

import { Settings } from '../models/Settings';
import { DataService, AppService } from '../providers/providers';

import * as i18next from 'i18next';
import * as i18nextXHRBackend from 'i18next-xhr-backend';

@Component({
  templateUrl: 'app.html',
})

export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any;
  authKey: string;
  private propertyKey: number;
  private _loading: Loading;
  pages: Array<{ title: string, component: any, icon: string }>;
  public viewReady: boolean = false;
  private _defaultLanguage: string = "en";

  constructor(
    public platform: Platform,
    public modalCtrl: ModalController,
    private dataService: DataService,
    private _loadingCtrl: LoadingController,
    private _alertCtrl: AlertController,
    private statusBar: StatusBar,
    private splashScreen: SplashScreen,
    private events: Events

  ) {
    this.rootPage = DashboardPage;
    this.authKey = localStorage.getItem(AppService.AUTH_KEY);
    if (!this.authKey) {
      this.rootPage = LoginPage;

    }
    else {
      this.propertyKey = parseInt(localStorage.getItem(AppService.PROPERTY_KEY));
      if (isNaN(this.propertyKey)) {
        this.rootPage = PropertyListPage;
      }
    }

    this.events.subscribe('loadingController', (data) => {
      this.manageLoadingDialog(data);
    });

    this.events.subscribe('displayConfirmationBox', (data) => {
      this.displayConfirmationBox(data.title, data.msg, data.pop);
    });

    this.events.subscribe('errorDisplay', (error) => {
      this.showError(error);

    });


    i18next.use(i18nextXHRBackend).init({
      debug: true,
      lng: this._defaultLanguage,
      fallbackLng: 'en',
      returnEmptyString: true,
      // initImmediate : false,
      defaultNS: 'static',
      ns: ['static', 'dynamic'],
      // mapping: { "specific_backend_message": "message_for_translate" },
      backend: {
        loadPath:  AppService.TRANSLATIONS_URI
      },
      interpolation: {
        prefix: "{{",
        suffix: "}}"
      }
    });



    // used for an example of ngFor and navigation - side bar menu
    this.pages = [
      { title: 'Dashboard', component: DashboardPage, icon: 'fa fa-home' },
      // { title: 'Arrivals', component: ArrivalsPage, icon: 'fa fa-sign-in' },
      // { title: 'Departures', component: DeparturesPage, icon: 'fa fa-sign-out' },
      // { title: 'Search Reservations', component: SearchBookingsPage, icon: 'fa fa-search' }
    ];

  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.


      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
  }

  openPage(page) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }

  manageLoadingDialog(data) {
    switch (data.action) {
      case 'show':
        this.showLoading(data.message);
        break;
      case 'hide':
        this.hideLoading();
        break;
    }
  }

  //loading dialog box
  showLoading(message?: string) {
    this._loading = this._loadingCtrl.create({
      content: message ? message : 'Please wait...'
    });
    this._loading.present();
  }


  hideLoading() {
    if (this._loading != null) {
      this._loading.dismiss();
      this._loading = null;
    }
  }


  logout() {

  }

  showError(error) {
    setTimeout(() => {
      this.hideLoading();
    });

    let alert = this._alertCtrl.create({
      title: 'Error',
      subTitle: error.message,
      buttons: ['OK']
    });
    alert.present(prompt);

    alert.onDidDismiss(() => {
      if (error.code == 401) {
        localStorage.clear();
        window.location.reload();
      }
    });
  }

  displayConfirmationBox(title: string, message: string, pop = false) {
    let alert = this._alertCtrl.create({
      title: title,
      subTitle: message,
      buttons: ['OK']
    });

    alert.onDidDismiss(() => {
      if (pop)
        this.nav.pop();
    });
    alert.present(prompt);
  }

}