vue v2.3.4
vue-i18n v7.0.3
Using with Laravel 5.4, and bundling assets with Webpack via Laravel Mix.
(Pending, will update post upon completion.)
Access to this.$t is provided via the 'this' binding solution provided by Vue
vue-i18n is not available (VueComponent property '_i18n' is null).
Other Vue instance properties are available in this context, such as this.$store when using vuex, as well as all component data, props and computed properties via 'this'.
An attempt to access this.$t generates an error:
TypeError: Cannot read property '_t' of null
Error is generated here, though the source cause is external of this: https://github.com/kazupon/vue-i18n/blob/9ef7b798e3c1d58dfae4f25e5e6b8c488b86d819/dist/vue-i18n.js#L111
Erm... I'm gonna close this for now as I need to narrow down more what's going on.
@SirLamer having the same issue, downgrading to ^5.x.x works for me
@SirLamer Have you investigated this problem? I just faced it today with vue 2.5.9 and vue-i18n 7.3.2
I think I avoided using vue-i18n in a promise context and haven't really confronted this issue again, sorry.
I know when I approached this before (above), after review I came to suspect I might have been doing something wrong.
@SirLamer but why did you close this issue? It's still reproducible.
It's really great to use this.$t for notifications (vue-notification) inside .then() or .catch().

I face this issue again with version 7.1.1. I use this.$t('xxxx') in a promise's then handler ( btw, it's a web app load in a Android webview, I think it may because user tap back button when request is loading )
Confirmed for me too with v7.6.0.
Happened in Promise#then(), but not all.
I have many promises using this plugin, the problem seems to be with long promises response time.
Can we reopen this ? I experienced the same error when using $t('xxx') inside a watcher callback.
version: [email protected]
As a workaround I stored the value outside the callback....
Uncaught TypeError: Cannot read property '_t' of null
at VueComponent.eval (vue-i18n.esm.js?7467:179)
at VueComponent.testPop (hello.vue?bfe5:219)
at eval (hello.vue?bfe5:223)
happened some times when using this.$t('langname') (not every time)
the same
Can this please be reopened -- this is still an issue in the latest release (8.3.1). You cannot access this.$t(...) inside of a Promise callback even though the rest of the Vue component works as expected on the this object.
@dmcknight26
Could you kindly prepare a reproducible code?
Lots of reopen requests so it shall be so.
I can confirm this is also an issue for me.
Sorry for the confusion but this does appear to be working correctly (at least it is for me now). After trying to create a test case I found the root of the problem which had to do with my application code. In short, the component in question, this, was in the process of being destroyed while also being used inside of some promises.
Honestly I'm not sure if this is really a bug or not, if I try to access other objects on this they still work correctly, e.g. this.$store, and even this.$t resolves to the current function -- it just doesn't work when used. I could probably throw together a test case if you think it's worth investigating...
OK, here's a test case: http://jsfiddle.net/jL7edyau/
Clicking the Remove button should cause the item to disappear and a success message to be displayed, however if you try you will get a console error: Cannot read property '_t' of null.
I suspect this is because clicking the button triggers a store action & commit which removes the item from the store (and thus starts destroying the component?). Then, back in the component in the .then you can no longer use this.$t.
I having the same issue,
use this.$root.$t() in promise works for me
I having the same issue,
usethis.$root.$t()in promise works for me
works, thanks. But it's just a workaround no real solution for this issue, right?
the funny think is on my webserver the app does not respond anymore when the error occurs. locally built for prod the error occurs but the app still works/react.
btw: i use vue-cli
Thank you volks
I had same problem, so I found a examples of nuxt.js official website:
https://nuxtjs.org/examples/i18n
following this examples configuration your project it will work.
don't forget about check that i18n.js of middleware and vuex folder.
{{$t('item')}} throws [Vue warn]: Error in render: "TypeError: Cannot read property '_t' of undefined" on 8.10.0 as well.
I had the same problem, this problem occurs only when I destroy the component, then looking at the source file I found beforeDestroy function:

This error happens because before the component is destroyed this function sets _i18n to null. To solve this, you can use the solution @hunterliu1003 or store the values in some variable out of the promise
In extend.js: Can't we simply put in a null check and print a warning if it is null everytime this.$i18n is accessed?
It is very cumbersome to have checks everywhere that test if the component was already destroyed.
I'm experiencing the same issue with [email protected] when using the new <MountingPortal> component.
Replacing $t() with this.$root.$t() doesn't seem to work.
I'm experiencing the same issue with [email protected] when using the new
<MountingPortal>component.Replacing
$t()withthis.$root.$t()doesn't seem to work.
I think this is because portal-vue docs (https://portal-vue.linusb.org/api/mounting-portal.html#props)
All of these props are not dynamic.
That means changing their values after initial render will have no effect.
this example shows that $t worked in <MountingPortal> component.
But after changing locale, $t('mesage.hello') didn't update the value.
https://codepen.io/hunterliu1003/pen/axVzJg
In master, beforeDestroy now looks as follows:
beforeDestroy (): void {
if (!this._i18n) { return }
const self = this
this.$nextTick(() => {
if (self._subscribing) {
self._i18n.unsubscribeDataChanging(self)
delete self._subscribing
}
if (self._i18nWatcher) {
self._i18nWatcher()
self._i18n.destroyVM()
delete self._i18nWatcher
}
if (self._localeWatcher) {
self._localeWatcher()
delete self._localeWatcher
}
self._i18n = null
})
}
The this.$nextTick construct was added in version 8.8 to address #499.
Wouldn't both #499 and this ticket be solved if we just drop the self._i18n = null line? The component is destroyed anyway moment later. I'd even say that the this.$nextTick construct isn't needed anymore then, but I might miss something there.
Happy to make the (very simple) pull.
@everhardt
Thanks for having eyes on this issue !!
PRs are welcome !!
Hi,
@everhardt I hope you don't mind I just made a PR as we just ran in the same issue. I did not touch the $nextTick stuff
I don't mind at all, the sooner this is fixed the better!
Still having this issue. Assigning variables outside the promise still causes the errors for me. using 8.14
That would make sense: the pull (#690) has not yet been merged (and there is no release yet that includes it).
I made another sample to reproduce the issue: https://jsfiddle.net/dskwp1ru/6/
This is still an issue, at least for us...
It seems that the PR (#690) was closed...
It would be nice to have a good solution for this... It's quite common to have async functions using this.$t in components. There must be a solution!
Maybe wait for all running promises to resolve before undefining this._i18n ?
Or maybe a "safe" $t function (maybe named $st) that would not throw an error if this._i18n is undefined and that could be used in promises?
I agree. I don't understand why not setting self._i18n = null might introduce a memory leak. If there are no references to it any more, won't it be removed by the garbage collector automatically?
If that's the case, the solution doesn't require any new function, only dropping the self._i18n = null line as the pull request did.
I agree. It is strange :) I used idea https://github.com/kazupon/vue-i18n/issues/184#issuecomment-446591824 and implemented wrapper
const I18nPlugin = {
install (Vue, options) {
const _$t = Vue.prototype.$t
Vue.prototype._$t = _$t
Vue.prototype.$t = function () {
if (this.$i18n) {
return _$t.apply(this, arguments)
} else {
return _$t.apply(this.$root, arguments)
}
}
}
}
// ....
Vue.use(VueI18n)
Vue.use(I18nPlugin)
I agree. I don't understand why not setting
self._i18n = nullmight introduce a memory leak. If there are no references to it any more, won't it be removed by the garbage collector automatically?If that's the case, the solution doesn't require any new function, only dropping the
self._i18n = nullline as the pull request did.
@redevening, could you please provide your view on this? You rejected https://github.com/kazupon/vue-i18n/pull/690, so you probably had reasons we have missed here.
@kazupon I think @redevening is not going to respond any time soon. What more information would you need to get this fixed? In my opinion #690 is a fine solution and good to go (see https://github.com/kazupon/vue-i18n/pull/690#discussion_r327501732).
Works fine locally and in staging, but on production with more data it fails during async
Example for Composition API users:
setup(props, vm) {
const state = reactive({
name: vm.root.$i18n.t("titles.overview"),
...
})
I created a sample application showing a working example
https://github.com/code1x1/vue-translation-test
it writes to requireMessage in a Promise.resolve the value returned by this.$t('general.form.input.required') which is working fine.
src/components/base/validation/form-validation.tsx
In Vue I18n 8.x, you can avoid this comment.
https://github.com/kazupon/vue-i18n/issues/184#issuecomment-446591824
Close the issue once, so we need to organize.
Most helpful comment
I having the same issue,
use
this.$root.$t()in promise works for me