Amber Fisher
Amber Fisher

Reputation: 63

i18n won't translate correctly when inside array or object in React Native

I'm trying to use i18n-js to translate some strings into other languages. If I have my code in normal code, it works. Ex:

//Displays "Something" (no quotes) where I want it
<Text> translate("Something"); </Text>

But if I put it inside an array or object, then call it later, it stops working and shows a missing message instead of the text I want translated. Ex:

const messages = {
    something: translate("Something"),
    // other translations...
}

// later on
// Displays "[missing "en.Something" translation]" (no quotes) where I want it
<Text> messages.something </Text>

The following is my code for my translate function, as well as the config for i18n. I'm using lodash-memoize, but that is unrelated to the issue. I've already checked that the text being passed to i18n.t() is the same (including type) no matter if it's in normal code or in the array, but it still doesn't return the correct thing. I have some error checking written up to avoid getting the missing message on screen, but that still doesn't fix the issue that it can't find the translation.

export const translationGetters = ({
    en: () => require('./translations/en.json'),
    es: () => require('./translations/es.json')
});

export const translate = memoize(
  (key, config) => {
    text = i18n.t(key, config)
    return text
  },
  (key, config) => (config ? key + JSON.stringify(config) : key)
);

export const setI18nConfig = () => {
  // fallback if no available language fits
  const fallback = { languageTag: "en", isRTL: false };

  const { languageTag, isRTL } =
    RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) ||
    fallback;

  // clear translation cache
  translate.cache.clear();
  // update layout direction
  I18nManager.forceRTL(isRTL);
  // set i18n-js config
  i18n.translations = { [languageTag]: translationGetters[languageTag]() };
  i18n.locale = languageTag;
};

I have no idea where to go on this. Any advice would be appreciated!

Upvotes: 3

Views: 1534

Answers (1)

Giovane de Loredo
Giovane de Loredo

Reputation: 21

Same problem here, workaround is to return array/object from inside a function:

Don't work

export const translations = [i18.t('path')]

Works

export function getTranslations() {
  const translations = [i18.t('path')]
  return translations
}

Upvotes: 1

Related Questions