can't access i18n translation inside vuex state.js file



  • I have a menu that I would like to store in vuex (rather than in the top level component). This menu has titles that are translated using vue-i18n. Inside the component, everything works great, but when I move my menu to my vuex store (inside state.js), my app refuses to load and I get errors that are all similar to:

    state.js?6b3c:16 Uncaught TypeError: src_boot_i18n__WEBPACK_IMPORTED_MODULE_0__.default.t is not a function

    my state.js file looks like this (and variations of it):

    // state.js
    import i18n from 'src/boot/i18n'
    export default {
      storeVersion: '1',
      version: {
        version: 0,
        date: 0,
        PWA: 0
      },
      menu: [
        {
          active: 'dashboard',
          main: [
            {
              id: 'dashboard',
              parent: null,
              title: this.$i18n.t('dashboard'),
              subtitle: this.$i18n.t('dashboardSub'),
              url: '/dashboard'
            }, // etc, etc
    

    I have tried replacing translatable strings like this.$i18n.t('dashboard') with:

    i18n.t('dashboard')
    $i18n.t('dashboard')
    app.i18n.t('dashboard')
    i18n.$t('dashboard')
    $i18n.$t('dashboard')
    app.i18n.$t('dashboard')
    i18n.tc('dashboard')
    $i18n.tc('dashboard')
    app.i18n.tc('dashboard')

    and so on, but I keep getting variations on the error above telling me that t (or tc, or whatever) is not a function. Any idea if this is even possible to do? vue-i18n is installed and working flawlessly in all of my components, I just wanted to move this one global menu item to the store, but it seems I am missing something fundamental. Any advice appreciated. Thanks!



  • What does your boot file look like ?

    Scott



  • Here is my boot file:

    import VueI18n from 'vue-i18n'
    import messages from 'src/i18n'
    
    let i18n
    
    export default ({ app, Vue }) => {
      Vue.use(VueI18n)
    
      // Set i18n instance on app
      app.i18n = new VueI18n({
        locale: 'en-gb',
        fallbackLocale: 'en-gb',
        silentFallbackWarn: true,
        silentTranslationWarn: true,
        // enableInSFC: true,
        messages
      })
      i18n = app.i18n
    }
    
    export { i18n }
    


  • Sorry, but I’m not certain what is wrong. It should work.

    Scott



  • Thanks for taking a look anyway, I appreciate it.



  • Interestingly, (and although it does not throw an error) when I console.log(i18n) I get undefined



  • And if I try to use const i18n = require('src/boot/i18n') instead of import, console.log(i18n) gives me:

    Module {__esModule: true, Symbol(Symbol.toStringTag): "Module", default: ƒ}
    default: ƒ (_ref)
    arguments: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.invokeGetter (<anonymous>:1:142)]
    caller: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.invokeGetter (<anonymous>:1:142)]
    length: 1
    name: ""
    prototype:
    constructor: ƒ (_ref)
    __proto__: Object
    __proto__: ƒ ()
    [[FunctionLocation]]: i18n.js?8847:6
    [[Scopes]]: Scopes[3]
    i18n: (...)
    Symbol(Symbol.toStringTag): "Module"
    __esModule: true
    get i18n: ƒ ()
    __proto__: Object
    


  • Aren’t the boot files supposed to be loaded before anything else? It feels like i18n is not being loaded in time and that is why it comes back undefined?



  • @ssuess your import seems to be wrong, should be with curly braces import { i18n } from 'src/boot/i18n'.



  • This post is deleted!


  • @metalsadman Thanks, I already tried it both ways, made no difference alas.



  • I think the problem is that the store is initialized before boot files, which is quite logical since boot files can access the store.

    So, a solution may be to defer translations. You may use a getter for that, with a map on your menu array that will replace fields by their translation.



  • Hmm you arr using this in your state. Remove thatt as well.



  • @metalsadman definitely not that, see above for all the variations I have tried.



  • @tof06 this sounds logical to me, do you have any example code you could point me to? Where exactly would this code go? in the state.js file or somewhere else?


Log in to reply