Search code examples
typescriptvue.jsvuejs3vue-composition-apivue-script-setup

Vue component's button callback: Cannot read properties of undefined


Using Vue3+typescript, I'm trying to use a library called gtag-vue to send google analytics events to my account.

The idea is that in a Vue component, when the user clicks a div, I'll send a custom event, myCustomEvent.

<template>
    <div v-on:click="displayWhatever(index)">SOME CONTENT HERE</div>
</template>
<script setup lang="ts">
import { event } from 'vue-gtag'

let selected = ref(-1);

const myComputedVar = computed(() => {
  return someVar.slice(//Some stuff here that returns a proper array with no errors);
}

function displayWhatever(this: any, index: number): void {
  selected.value = index;
  event('myCustomEvent', {
    value1: this.myComputedVar[index].value1,
    value2: this.myComputedVar[index].value2
  })
}
</script>

Whenever I use it in development, by running npm run dev it works perfectly! But when I do npm run build, with no errors and upload it, I get this error in the Javascript console:

TypeError: Cannot read properties of undefined (reading 'myComputedVar')
    at y (index-39a6e75d.js:1535:23997)
    at onClick (index-39a6e75d.js:1535:25733)
    at xn (index-39a6e75d.js:1:13194)
    at cr (index-39a6e75d.js:1:13273)
    at HTMLDivElement.r (index-39a6e75d.js:1:56693)

So it looks like this is not correctly set up in the production build. But I really can't understand why. I have tried other methods, like removing the this from the function, but then I get compile errors when doing npm run build.

I'm using Vite by the way, in case it makes a difference.


Solution

  • There's no this (that refers to component instance as in options API) in script setup syntax, you should use computedVar.value instead of this.computedVar :

    function displayWhatever( index: number): void {
      selected.value = index;
      event('myCustomEvent', {
        value1: myComputedVar.value[index].value1,
        value2: myComputedVar.value[index].value2
      })
    }