Skip to content

Cannot read property 'toResolveHierarchy' of undefined #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
brettdewoody opened this issue Nov 9, 2019 · 4 comments
Open

Cannot read property 'toResolveHierarchy' of undefined #9

brettdewoody opened this issue Nov 9, 2019 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@brettdewoody
Copy link

brettdewoody commented Nov 9, 2019

I'm using storybook-addon-i18n and have a conditional i18next configuration depending on an environment variable. In Storybook I bundle the translation files. In my actual web app I use the i18next-xhr-backend to load the translations from my server.

To do this I define a STORYBOOK_ env variable when running npm run storybook, and in the configuration of i18n conditionally use XHR, or import the translations as resources. Like this:

const locales = ['en', 'de']
const isDev = process.env.NODE_ENV !== 'production'
const useXHR = process.env.STORYBOOK_USE_I18N_XHR !== 'false'

const options = {
  debug: true,
  preload: ['en'],
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false, // not needed for react as it escapes by default
  },
}

const loadTranslationFiles = async (options, useXHR, XHR, locales) => {
  // In the app we load translation files with XHR
  // In Storybook we bundle the translation files
  if (useXHR) {
    i18n.use(XHR)
    const backend = {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    }
    return {
      ...options,
      backend,
    }
  } else {
    // Load all the translation files using a dynamic import
    return await Promise.all(locales.map((locale) => import(`../../public/locales/${locale}/translation.json`))).then(
      ([...translations]) => {
        const resources = translations.reduce((result, translation, idx) => {
          result[locales[idx]] = { translation: translation.default }
          return result
        }, {})

        return {
          ...options,
          resources,
        }
      },
    )
  }
}

const optionsWithLngs = await loadTranslationFiles(options, useXHR, XHR, locales)

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(optionsWithLngs)

This works until I refresh Storybook. When I do it throws the following error:

Cannot read property 'toResolveHierarchy' of undefined
TypeError: Cannot read property 'toResolveHierarchy' of undefined
    at setLng (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:91445:62)
    at I18n.changeLanguage (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:91462:9)
    at http://localhost:9002/main.86a2811ac76424356127.bundle.js:318:14
    at commitHookEffectList (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:130174:26)
    at commitPassiveHookEffects (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:130198:3)
    at HTMLUnknownElement.callCallback (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113040:14)
    at Object.invokeGuardedCallbackDev (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113090:16)
    at invokeGuardedCallback (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113147:31)
    at commitPassiveEffects (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:131665:9)
    at wrapped (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:143892:34)

If I switch to a different story everything starts working again.

I see some items in the changelog related to fixing this issue of toResolveHierarchy returning undefined, but on much earlier versions if i18n.

Package versions
"i18next": "^19.0.0",
"i18next-browser-languagedetector": "^4.0.1",
"i18next-xhr-backend": "^3.2.2",
"react-i18next": "^11.0.1",
"storybook-addon-i18n": "^5.1.11",
"@storybook/react": "^5.2.5",

@alexeychikk
Copy link
Collaborator

@brettdewoody storybook-addon-i18n is library agnostic. It means that it doesn't depend on any particular localization library. As you can see in our package.json we don't have any i18n dependencies. So the problem is most likely resides in your .storybook/config.js, particularly in addParameters({ i18n: {...} }).
If you could share your config I may be able to help.

@alexeychikk alexeychikk added the help wanted Extra attention is needed label Feb 21, 2020
@ldeveber
Copy link

ldeveber commented Mar 3, 2020

I am also seeing this, but I'm using react-i18next client side.

    "i18next": "^19.0.3",
    "react-i18next": "^11.3.1",
    "@storybook/core": "^5.3.14",
    "@storybook/react": "^5.3.14",
    "storybook-addon-i18n": "^5.1.13",

I'm also using the new config files not the old config.js: https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78

@ldeveber
Copy link

ldeveber commented Mar 3, 2020

I am also seeing this, but I'm using react-i18next client side.

    "i18next": "^19.0.3",
    "react-i18next": "^11.3.1",
    "@storybook/core": "^5.3.14",
    "@storybook/react": "^5.3.14",
    "storybook-addon-i18n": "^5.1.13",

I'm also using the new config files not the old config.js: https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78

...just kidding. I got it working client side, see below:

preview.js:

import { addParameters, addDecorator } from '@storybook/react';
import { withI18n } from 'storybook-addon-i18n';
import i18n from '../src/i18n';
import { I18nextProvider } from 'react-i18next';

addParameters({
  i18n: {
    provider: I18nProviderWrapper,
    providerProps: {
      i18n
    },
    supportedLocales: [ 'en' ],
  },
});

addDecorator(withI18n);

../src/i18n:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import * as en from './locales/en'; // these are the translated files

i18n.use(initReactI18next).init({
  // for all options read: https://www.i18next.com/overview/configuration-options
  fallbackLng: 'en',
  languages: [ 'en' ],
  debug: false,

  lng: 'en',
  returnObjectTrees: true,
  interpolation: {
    escapeValue: false, // not needed for react as it escapes by default
  },
  resources: {
    en,
  },
});

export default i18n;

@alexeychikk
Copy link
Collaborator

@ldeveber Thanks for your reply.
From your preview.js it's not clear what is I18nProviderWrapper. Could you please share the code of it so that others could benefit from your solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants