0

Hi take a look this code, if I set the message asynchronously whenever new data resolved, it doesn't re render the translation.

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script>

<div id="app">
  <p>{{ $t("home") }}</p>
</div>

const locale = {
    id: {
    home: 'Beranda'
  },
  en: {
    home: 'Home'
  }
}

const i18n = new VueI18n({
  locale: 'id'
})

new Vue({
  el: '#app',
  i18n,
  created () {
    setTimeout(() => {
    this.$i18n.setLocaleMessage(locale)
  }, 100)
 }
})

Updated

My current workaround is define a method that return Promise and the variable that will hold the text. When the promise is resolved, then I set the translation.

const locale = {
 id: {
   home: 'Beranda'
  },
  en: {
   home: 'Home'
  }
}

const i18n = new VueI18n({
  locale: 'id'
})

new Vue({
 el: '#app',
 i18n,
  data: {
   text: null
  },
  methods: {
   getData () {
     return new Promise(resolve => {
       setTimeout(() => {
          this.$i18n.setLocaleMessage('id', locale.id)
          this.$i18n.setLocaleMessage('en', locale.en)
          resolve()
        }, 1000)
      })
    }
  },
  created () {
   this.getData().then(() => {
     this.text = this.$t('home')
    })
  }
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script>

<div id="app">
  <p>{{ text }}</p>
</div>
Jefry Dewangga
  • 819
  • 10
  • 24

1 Answers1

0

Looking at the docs, you need to set the keypath.

Define:

const messages = { // keypath
    id: {
    home: 'Beranda'
  },
  en: {
    home: 'Home'
  }
}

And use the messages to set the default language:

const i18n = new VueI18n({
  locale: 'id', // default locale
  messages // keypath is set
})

If you use keypath name other than messages:

const translations = { // different keypath constant
    id: {
    home: 'Beranda'
  },
  en: {
    home: 'Home'
  }
}



const i18n = new VueI18n({
  locale: 'id',
  messages: translations // messages now use translations keypath
})


new Vue({
    el: '#app',
    i18n,
  /* created () { // you don't need to set locale here
    setTimeout(() => {
      this.$i18n.setLocaleMessage(locale)
    }, 100)
  } */
})

Here's a working demo


Update

As per your comment, to set locale asynchronously - you can use like this:

const i18n = new VueI18n({
  messages
})

new Vue({
    el: '#app',
    i18n,
  created () {
    setTimeout(() => {
      this.$i18n.locale  = 'id'
    }, 100)
  }
})

demo

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
  • Hi, I've tried your suggestion. Changing to `i18n` return `(index):68 Uncaught TypeError: Cannot read property 'setLocaleMessage' of undefined` on the console. Take a look this reproduction link https://jsfiddle.net/jefrydco/q5d3cp9a/13/, – Jefry Dewangga Mar 22 '18 at 04:19
  • 1
    Hi I set the localeMessage using setTimeout is simulate the network request. I wanna get the message dynamically from the API, so it must be asynchronous execution. – Jefry Dewangga Mar 22 '18 at 06:28
  • 1
    Not the current locale object but the message object itself. Let met clarify, here I wanna dynamically add the message object gotten from network request. The translation data source is from API. Not defined locally. On your answer, you defined the message object when instantiate the VueI18n constructor. Take a look my current workaround updated above. – Jefry Dewangga Mar 22 '18 at 13:02
  • You should use `const i18n = new VueI18n({ messages: locale })` and set locale 'id' or 'en' as my last updated answer. – Bhojendra Rauniyar Mar 22 '18 at 13:37
  • @JefryDewangga Did you manage to achieve it, could you please share. – Peter Jul 15 '19 at 12:03
  • 1
    @VishalGulati the workaround that I achieve is on the updated section on this post above – Jefry Dewangga Jul 16 '19 at 09:17