Skip to content

this.$t is not a function in a class component #1767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Mikilll94 opened this issue Jan 11, 2021 · 11 comments
Closed

this.$t is not a function in a class component #1767

Mikilll94 opened this issue Jan 11, 2021 · 11 comments

Comments

@Mikilll94
Copy link

Mikilll94 commented Jan 11, 2021

Subject of the issue

I have the following component

<template>
  <div>{{someData}}</div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class App extends Vue {
  private someData = this.$t("message");
}
</script>

and the following unit test

import { mount } from '@vue/test-utils'
import App from '@/App.vue'

describe('App.vue', () => {
  it('some unit test', () => {
    const wrapper = mount(App, {
      mocks: {
        $t: (key: string) => key
      }
    });
    expect(wrapper).toBeDefined();
  })
})

When running this unit test, it fails with the following error:

 FAIL  tests/unit/example.spec.ts
  HelloWorld.vue
    ✕ some unit test (22ms)

  ● HelloWorld.vue › some unit test

    TypeError: this.$t is not a function

       8 | @Component
       9 | export default class App extends Vue {
    > 10 |   private someData = this.$t("message");
         | ^
      11 | }
      12 | </script>
      13 | 

      at new App (src/App.vue:10:1)
      at collectDataFromConstructor (node_modules/vue-class-component/dist/vue-class-component.common.js:165:14)
      at VueComponent.data (node_modules/vue-class-component/dist/vue-class-component.common.js:227:14)
      at getData (node_modules/vue/dist/vue.runtime.common.dev.js:4732:17)
      at initData (node_modules/vue/dist/vue.runtime.common.dev.js:4689:7)
      at initState (node_modules/vue/dist/vue.runtime.common.dev.js:4628:5)
      at VueComponent.Vue._init (node_modules/vue/dist/vue.runtime.common.dev.js:4987:5)
      at new VueComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5134:12)
      at createComponentInstanceForVnode (node_modules/vue/dist/vue.runtime.common.dev.js:3277:10)
      at init (node_modules/vue/dist/vue.runtime.common.dev.js:3108:45)
      at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5958:9)
      at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5905:9)
      at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6455:7)
      at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3933:19)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4054:10)
      at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4465:25)
      at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4454:12)
      at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4061:3)
      at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8392:10)
      at mount (node_modules/@vue/test-utils/dist/vue-test-utils.js:13991:21)
      at Object.<anonymous> (tests/unit/example.spec.ts:6:21)

Steps to reproduce

Just run unit tests in this project:
i18n-test.zip

Expected behaviour

Error this.$t is not a function should not occur. The $t function is mocked.

Actual behaviour

An error this.$t is not a function is thrown.

Additional context

If I convert someData to computed property, like this:

<template>
  <div>{{someData}}</div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class App extends Vue {
  private get someData() {
    return this.$t("message");
  }
</script>

the error is gone.

@lmiller1990
Copy link
Member

I am not sure how vue-class-component works under the hood - we just mutate Vue.prototype for mocked properties. We may need to look into what VCC is actually doing to patch this.

I didn't even know you could access this when setting default values for class properties 🤔

@Mikilll94
Copy link
Author

Mikilll94 commented Jan 16, 2021

@lmiller1990
I have created the same issue in vue-class-component repo. We will see in which repo the bug is present.

I didn't even know you could access this when setting default values for class properties

For me, this seems quite normal. Without using VCC you can write code like this:

data() {
    return {
        someData: this.$t("message");
    }
}

@alexanderop
Copy link

I also have the same problem. The only thing I see this would work is to have a base class and a constrcutor for the global functions like

  public constructor() {
    super();
    this.$t = implemntation;
  }

and let the child Components extend it from there

What i get as a error when I try to access this.$t is __this.$t is not defined

@lmiller1990
Copy link
Member

^ good work around - I think we need something in VCC to make this work with test utils...

@Evertvdw
Copy link

Evertvdw commented May 7, 2021

I guess this is something which needs to be fixed in vue-class-component. I have this issue when running the app as well, so it is not only something that happens when unit testing.

It also happens when you access this.$store in a variable declaration in a class component. So it is not only due to the implementation of i18n for instance.

@lmiller1990
Copy link
Member

If you can reproduce this in VCC without Test Utils, definitely post an issue there.

@mmouterde
Copy link

#1815 (comment) was relevant for me

@turgayh
Copy link

turgayh commented Sep 13, 2021

i m facing some issue . is there any update for that ?

@lmiller1990
Copy link
Member

lmiller1990 commented Sep 24, 2021

There is no obvious fix we can do in VTU, from waht what I can see. Aside from adding some code in Vue Class Component to support this kind of behavior, which is not a library I work on or use, so I don't see this getting solved in the foreseeable future.

@Lightlce
Copy link

Hi i'm facing this too.

@lmiller1990
Copy link
Member

No update and unlikely this will be fixed - Vue Class Component seems deprecated, and I don't think we can fix this here, anyway -- it would be in that repo. See my post here: #1767 (comment)

If someone wants to try fixing it, that'd be great, but I won't be working on this at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants