No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

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

    Framework
    6
    17
    3314
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • ssuess
      ssuess last edited by

      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!

      1 Reply Last reply Reply Quote 0
      • s.molinari
        s.molinari last edited by

        What does your boot file look like ?

        Scott

        1 Reply Last reply Reply Quote 0
        • ssuess
          ssuess last edited by ssuess

          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 }
          
          1 Reply Last reply Reply Quote 0
          • s.molinari
            s.molinari last edited by

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

            Scott

            1 Reply Last reply Reply Quote 0
            • ssuess
              ssuess last edited by

              Thanks for taking a look anyway, I appreciate it.

              1 Reply Last reply Reply Quote 0
              • ssuess
                ssuess last edited by

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

                1 Reply Last reply Reply Quote 0
                • ssuess
                  ssuess last edited by ssuess

                  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
                  
                  1 Reply Last reply Reply Quote 0
                  • ssuess
                    ssuess last edited by

                    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?

                    metalsadman 1 Reply Last reply Reply Quote 0
                    • metalsadman
                      metalsadman @ssuess last edited by

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

                      ssuess 1 Reply Last reply Reply Quote 0
                      • ssuess
                        ssuess last edited by

                        This post is deleted!
                        1 Reply Last reply Reply Quote 0
                        • ssuess
                          ssuess @metalsadman last edited by

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

                          1 Reply Last reply Reply Quote 0
                          • T
                            tof06 last edited by

                            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.

                            ssuess 1 Reply Last reply Reply Quote 1
                            • metalsadman
                              metalsadman last edited by

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

                              ssuess 1 Reply Last reply Reply Quote 0
                              • ssuess
                                ssuess @metalsadman last edited by

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

                                1 Reply Last reply Reply Quote 0
                                • ssuess
                                  ssuess @tof06 last edited by

                                  @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?

                                  1 Reply Last reply Reply Quote 0
                                  • M
                                    mas last edited by

                                    I imported i18n in vuex modules where I need it this way:

                                    import { i18n } from 'src/boot/i18n'
                                    

                                    and then accessed i18n translations in my vuex actions this way:

                                    let myMessage = i18n.t('messages.myMessage')
                                    

                                    Works like magic.

                                    1 Reply Last reply Reply Quote 1
                                    • M
                                      Musulmon last edited by Musulmon

                                      You should import i18n as like

                                      import {i18n} from '../boot/i18n'
                                      

                                      because i18n is not default exported.

                                      1 Reply Last reply Reply Quote 1
                                      • First post
                                        Last post