I m trying to load the localization from HTTP call as i want the languages to be dynamic and manageable, rather than shipping it with the application.
I did a work around using the SSR sample and some of my own implementation. But on the initial render the language does not loading. When changing the route client-side things are getting updated.
i18n.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import en from './en.json'
import ar from './ar.json'
import axios from 'axios'
Vue.use(VueI18n)
const fallbackLocale = 'en'
let defaultLocale = 'ar'
export const i18n = new VueI18n({
locale: defaultLocale, // set locale
fallbackLocale: fallbackLocale,
messages: {
'en': en
}
})
export function createI18n () {
return i18n
}
Router - router.beforeEach
router.beforeEach((to, from, next) => {
if (router.app.$store) {
router.app.$store
.dispatch('getI18nData')
.then(function(){
router.app.$i18n.setLocaleMessage('ar',router.app.$store.getters.getLocale)
return next()
})
.catch(() => console.log('getI18nData-error'))
} else {
next()
}
})
Store Action - to fetch locale
getI18nData ({ commit }) {
try {
axios.get('http://localhost:8080/lang?lang=ar')
.then(function (response) {
let locale = response.data
commit('setLocale', { locale })
})
.catch(function (error) {
console.log('Error:getI18nData')
})
} catch (error) {
console.error(error);
}
}
Findings:
i18n is initializing before router.beforeEach
where it should initialize after router.beforeEach
.
Alright, to be a little bit more detailed: You don't want to mix try/catch with your promise-chain, but you need to return a promise from getI18nData
or dispatch won't wait. So you either:
getI18nData ({ commit }) {
// axios.get() returns a promise already, so we can just return the whole thing:
return axios
.get('http://localhost:8080/lang?lang=ar')
.then(function (response) {
let locale = response.data
commit('setLocale', { locale })
})
.catch(function (error) {
console.log('Error:getI18nData')
});
}
Or your use async/await (which does allow try/catch):
async getI18nData ({ commit }) {
try {
let response = await axios.get('http://localhost:8080/lang?lang=ar');
let locale = response.data
commit('setLocale', { locale })
} catch (error) {
console.error(error);
}
}
I'd like to add that I do like the async/await option better, but in vuex-land it usually leads to you having to make everything async/await (if you use nested dispatch calls). So depending on the rest of your code-base, it might be easier to just return the promise.