ngx-translate / core

The internationalization (i18n) library for Angular
MIT License
4.5k stars 572 forks source link

Custom TranslateLoader only observe once #700

Open mparpaillon opened 6 years ago

mparpaillon commented 6 years ago

I'm submitting a ... (check one with "x")

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

Current behavior When I return an Observable in my TranslateFirebaseLoader inside a Observable.merge, only the first Observable emits.

Expected/desired behavior The TranslateFirebaseLoader should check first LocalStorage and emits the value, then fetch remote translations, update localStorage and emits the updated value.

Reproduction of the problem

Here is my code:

import { Observable } from 'rxjs/Observable';
import isEmpty from 'lodash.isempty';

const LANG_LS_DATA_KEY = 'i18n-ui-';

const TranslateFirebaseLoader = (function () {
  function TranslateFirebaseLoader(db, ls, dialogProvider, path) {
    this.db = db;
    this.ls = ls;
    this.dialogProvider = dialogProvider;
    this.path = path;
  }

  /**
   * Gets the translations from the server
   * @param langCode
   * @returns {any}
   */
  TranslateFirebaseLoader.prototype.getTranslation = function(langCode) {
    return this.getLocalTranslation(langCode)
    .merge(this.getRemoteTranslation(langCode));
  };

  TranslateFirebaseLoader.prototype.getLocalTranslation = function(langCode) {
    const localTranslation = this.ls.get(LANG_LS_DATA_KEY + langCode, {});

    return Observable.of(localTranslation);
  }

  TranslateFirebaseLoader.prototype.getRemoteTranslation = function(langCode) {
    const localTranslation = this.ls.get(LANG_LS_DATA_KEY + langCode, false);

    if (!localTranslation) {
      this.dialogProvider.showLoader('fetching-i18n-UI', `Fetching translations...`);
    }

    const path = this.path.replace('{lang}', langCode);

    return this.db.doc(path).valueChanges().map(data => {
      // if (isEmpty(data)) return Observable.of({});

      this.dialogProvider.hideLoader('fetching-i18n-UI');

      this.ls.set(LANG_LS_DATA_KEY + langCode, data.ui);

      return data.ui;
    });
  }

  return TranslateFirebaseLoader;
}());

export { TranslateFirebaseLoader };

ngx-translate version: 8.0.0 Angular version: 4.4.3 Ionic version: 3.7.1 Browser: all

Thanks

Dyljyn commented 6 years ago

I have a similar problem where I'm using a store that gets filled with translations from an API.

Added this piece of code as a quick fix

this.store
    .select(state => state.ui.i18n)
    .subscribe(() => this.translate.reloadLang(this.translate.currentLang));