question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeError: this.$t is not a function in an async method, after component is not rendered anymore

See original GitHub issue

Reporting a bug?

I get the following error when I try to call $t, in an async method that makes the current component not being rendered anymore:

Uncaught (in promise) TypeError: this.$t is not a function
    toggle DisappearComponent.vue:13
    step tslib.es6.js:100
    verb tslib.es6.js:81
    fulfilled tslib.es6.js:71
    promise callback*step tslib.es6.js:73
    __awaiter tslib.es6.js:74
    __awaiter tslib.es6.js:70
    toggle cjs.js:11
    0 DisappearComponent.vue:8
    callWithErrorHandling runtime-core.esm-bundler.js:155
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:164
    invoker runtime-dom.esm-bundler.js:369
    addEventListener runtime-dom.esm-bundler.js:319
    patchEvent runtime-dom.esm-bundler.js:337
    patchProp runtime-dom.esm-bundler.js:401
    mountElement runtime-core.esm-bundler.js:4632
    processElement runtime-core.esm-bundler.js:4595
    patch runtime-core.esm-bundler.js:4515
    componentUpdateFn runtime-core.esm-bundler.js:5066
    run reactivity.esm-bundler.js:185
    setupRenderEffect runtime-core.esm-bundler.js:5185
    mountComponent runtime-core.esm-bundler.js:4968
    processComponent runtime-core.esm-bundler.js:4926
    patch runtime-core.esm-bundler.js:4518
    mountChildren runtime-core.esm-bundler.js:4714
    mountElement runtime-core.esm-bundler.js:4623
    processElement runtime-core.esm-bundler.js:4595
    patch runtime-core.esm-bundler.js:4515
    mountChildren runtime-core.esm-bundler.js:4714
    processFragment runtime-core.esm-bundler.js:4885
    patch runtime-core.esm-bundler.js:4511
    componentUpdateFn runtime-core.esm-bundler.js:5066
    run reactivity.esm-bundler.js:185
    setupRenderEffect runtime-core.esm-bundler.js:5185
    mountComponent runtime-core.esm-bundler.js:4968
    processComponent runtime-core.esm-bundler.js:4926
    patch runtime-core.esm-bundler.js:4518
    render runtime-core.esm-bundler.js:5686
    mount runtime-core.esm-bundler.js:3903
    mount runtime-dom.esm-bundler.js:1593
    <anonymous> main.ts:16
    ts app.js:1069
    __webpack_require__ app.js:849
    fn app.js:151
    1 app.js:1082
    __webpack_require__ app.js:849
    checkDeferredModules app.js:46
    <anonymous> app.js:925
    <anonymous> app.js:928

More specifically, I think the problematic case can be broken down as follow:

  • Have a component with a method with an await call (slow) followed by calling $t
  • Call this method
  • Make the component not being rendered anymore before the aforementioned methods complete
  • Expect the $t call to happen and respond normally after the await part is finished

Expected behavior

I think I should be able to run a method without having to care about the fact that the component is not being rendered anymore after an await call.

Please let me know if this assumption is not reasonable, as I’m not completely sure it is fine. Also if you think something is to be fixed on the vue-core side and not in this repo, please do tell me as well 🙇

Reproduction

Please use the async-translation branch in this repository: https://github.com/CamilleDrapier/vue-i18n-test/tree/async-translation

Clicking on the “Hide and display translation” button triggers an error

System Info

System:
    OS: Linux 5.15 Manjaro Linux
    CPU: (12) x64 Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz
    Memory: 16.48 GB / 30.99 GB
    Container: Yes
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    Yarn: 1.22.18 - ~/.nvm/versions/node/v16.14.2/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
  Browsers:
    Chromium: 100.0.4896.127
    Firefox: 99.0.1
  npmPackages:
    @vue/cli-plugin-eslint: ~4.5.0 => 4.5.15 
    @vue/cli-plugin-typescript: ~4.5.0 => 4.5.15 
    @vue/cli-service: ~4.5.0 => 4.5.15 
    @vue/compiler-sfc: ^3.0.0 => 3.2.33 
    @vue/eslint-config-standard: ^5.1.2 => 5.1.2 
    @vue/eslint-config-typescript: ^7.0.0 => 7.0.0 
    vue: ^3.2.33 => 3.2.33 
    vue-i18n: ^9.2.0-beta.35 => 9.2.0-beta.35

Screenshot

No response

Additional context

At least in my real-life application that was built with vue2 // vue-i18n v8, I was able to do similar things with no problems until I tried upgrading to vue3 // vue-i18n v9.

If this is still supported then maybe the problem is that the translation plugin of the component is unloaded/removed too early in the life-cycle?

Could be related to: https://github.com/intlify/vue-i18n-next/issues/609

Validations

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
CamilleDrapiercommented, May 11, 2022

Another workaround that seems to be working is the following, but I’m unsure if that is a reasonable enough workaround, and if it will not backfire horribly in some cases?

  app.use({
    install(appInner) {
      appInner.config.globalProperties.$t = i18n.global.t;
      appInner.config.globalProperties.$te = i18n.global.te;
    },
  });

I made a small branch with this change on my repo under async-translation-hack-install

Also, I do not know if that is related to this, but inside my real-life application, if I put my current component to the console when i18n’s $t is having this “undefined” problem, it seems that other plugins such as $route or $store are available at that point.

2reactions
edwinofsakhcommented, Sep 5, 2022

It looks like in legacy mode we use mixin that removes $t on unmount hook. https://github.com/intlify/vue-i18n-next/blob/v9.2.2/packages/vue-i18n-core/src/mixins/next.ts

Read more comments on GitHub >

github_iconTop Results From Across the Web

$t is undefined in child component · Issue #609 · intlify/vue-i18n-next ...
Cannot use $t in child component if loaded from Vuex module and passed to ... a function in an async method, after component...
Read more >
“FunctionName” is not a function async and await - React Native
I extract data from the webview with onMessage . According to the incoming data, I have to call the _addToOrder function. class ...
Read more >
instanceof - JavaScript - MDN Web Docs
The instanceof operator tests to see if the prototype property of a constructor appears anywhere in the prototype chain of an object.
Read more >
Testing-library: avoid these mistakes in async tests
What's going on when render is awaited? Well, MDN is very clear about it: If the value of the expression following the await...
Read more >
What does "TypeError: this[t] is not a function" mean? - Reddit
Your code has been compiled by a builder, like webpack or vite. Unless there is a backtrace with the error (possibly enhanced with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found