Jonathan
Jonathan

Reputation: 185

Property in Data is undefined inside methods() method

I'm brand new to Vue so trying to understand the basics so far. I'm using Vue 3.

My intention is to:

It's at this final stage that the error occurs, specifically the line getGeneMutationData: () => this.queryConstraints.push({

Error:

Uncaught TypeError: Cannot read properties of undefined (reading 'queryConstraints')
    at Proxy.getGeneMutationData (Query.vue?12c2:46:14)
    at eval (runtime-dom.esm-bundler.js?3191:380:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?a261:155:1)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?a261:164:1)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?a261:174:1)
    at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js?3191:366:39)

I'm not sure why this isn't working, based on the documentation I'm not sure what's different in the approaches:

data() {
    return { count: 4 }
  },
  methods: {
    increment() {
      // `this` will refer to the component instance
      this.count++
    }
  }

Here's a minimised of my code:

<template>
  <select v-model="selectedGeneMutation">
    <option v-for="geneMutation in geneMutations" :key="geneMutation">{{geneMutation}}</option>
  </select>
  <input type="button" @click="getGeneMutationData">Get results</input>
</template>

<script>
  export default {
    name: 'Home',
    data: () => ({
      geneMutations: ['ACTC',
                      'MYBPC3'
      ],
      queryConstraints: [],
      selectedGeneMutation: ''
    }),
    setup() {},
    methods: {
      getGeneMutationData: () => this.queryConstraints.push({
        fieldPath: this.selectedGeneMutation,
        opStr: '==',
        value: true
      })
    }
  };
</script>

Any help as to why I can't access the properties in 'data' would really be appreciated

Upvotes: 2

Views: 1120

Answers (2)

Oleg Naumov
Oleg Naumov

Reputation: 587

You are using an Arrow Function. It's limited and doesn't have its own binding to this, that's why your method fails. The documentation you're referring to is using a traditional function expression.

So in your case try this:

getGeneMutationData: function () {
  this.queryConstraints.push({
  fieldPath: this.selectedGeneMutation,
  opStr: "==",
  value: true,
});

EDIT: Actually Nikola Pavicevic's answer is correct. Yes, using a traditional function expression solves your problem, however, it seems like mixing up composition and options API (or rather not understanding the difference between the two) is what caused the issue in the first place. In Vue 3, when you use composition API you're not using this. The setup() method returns an object, and all of its properties are exposed to the rest of the component.

Upvotes: 4

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23500

You should not mix composition and options API (this is not the same, also, there is no methods in composition API), try like following snippet (composition API) or you can move your methods to options API (remove setup function):

const { ref } = Vue
const App = {
  setup() {
    const geneMutations = ref(['ACTC', 'MYBPC3'])
    let queryConstraints = ref([])
    const selectedGeneMutation = ref('')
    const getGeneMutationData = () =>  {
      queryConstraints.value.push({
        fieldPath: selectedGeneMutation.value,
        opStr: '==',
        value: true
      })
    }
    return {  
      geneMutations, queryConstraints, selectedGeneMutation, getGeneMutationData
    };
  }
}
Vue.createApp(App)
  .mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
<div id="app">
  <select v-model="selectedGeneMutation">
    <option v-for="geneMutation in geneMutations" :key="geneMutation">{{geneMutation}}</option>
  </select>
  <input type="button" @click="getGeneMutationData" value="Get results" />
  <h3>{{ queryConstraints }}</h3>
</div>

Upvotes: 1

Related Questions