2
votes

i'm trying to move my locales to a database. Right now we are using i18n and this i s the configuration:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { defaultLanguage, languagesResources } from '@config/languageConfig';
import { makeSelectBaseLanguage } from '@redux/settings/selectors';
import { store } from '@redux/index';
import Fetch from 'i18next-fetch-backend';

// translation catalog
console.log('fetch', Fetch);
const languageDetector = {
  type: 'languageDetector',
  async: true,
  detect: (cb: (baseLanguage: string) => void) => {
    let prevLanguage: string;
    store.subscribe(() => {
      const selectBaseLanguage = makeSelectBaseLanguage();
      console.log('ciaoo', selectBaseLanguage);
      const baseLanguage = selectBaseLanguage(store.getState());
      if (baseLanguage !== prevLanguage) {
        prevLanguage = baseLanguage;
        cb(baseLanguage);
      }
    });
  },
  init: () => {},
  cacheUserLanguage: () => {},
};

i18n
  .use(languageDetector)
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    debug: true,
    resources: languagesResources,
    // language to use if translations in user language are not available.
    fallbackLng: defaultLanguage,
    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
    },

    react: {
      wait: false,
      useSuspense: false,
    },
  });

export default i18n;

this is the resources languageResources

    /* tslint:disable */
import * as en from './locales/en.json';
import * as en_HttpError from './locales/en.httpError.json';
import * as tr from './locales/tr.json';
import * as tr_HttpError from './locales/tr.httpError.json';
import * as en_Guide from './locales/en.guide.json';
import * as tr_Guide from './locales/tr.guide.json';
import { onReadTranslationData } from '@utils/realtimeDatabase';

const data = onReadTranslationData();
console.log('dataaa', data);
export const scrollPickerLanguage = [
  {
    id: 1,
    title: 'ENGLISH',
    value: 'en',
  },
  {
    id: 2,
    title: 'TURKISH',
    value: 'tr',
  },
];
export const defaultLanguage = 'en';
export const languagesResources = {
  en: { ...en, httpError: en_HttpError, guide: en_Guide },
  tr: { ...tr, httpError: tr_HttpError, guide: tr_Guide },
};

and this is the function

import database from '@react-native-firebase/database';

export const onReadTranslationData = () => {
  const translations = database()
    .ref('/languages')
    .once('value')
    .then(snapshot => {
      const languages = { en: snapshot.child('en').val(), tr: snapshot.child('tr').val() };
      return languages;
    });
  return translations;
};

now, my main problem is that if I receive the correct data from onReadTranslationData and i try to change tr: { ...tr, httpError: tr_HttpError, guide: tr_Guide }, in languageResources I'm not able to even launch the app, this is because I receive the data in an async way and the first data is null.

There is a way to avoid this error, and load the translations from an api/database ?

I tried to use this library https://github.com/perrin4869/i18next-fetch-backend but i haven't a good result.

1

1 Answers

2
votes

You should add the translations after init using addResourceBundle.

import database from '@react-native-firebase/database';

export const onReadTranslationData = () => {
  const translations = database()
    .ref('/languages')
    .once('value')
    .then(snapshot => {
      // this will load the new languages
      i18next.addResourceBundle('en', 'namespace1', snapshot.child('en').val());
      i18next.addResourceBundle('tr', 'namespace1', snapshot.child('tr').val());
    });
  return translations;
};