I'm brand new to Vue so trying to understand the basics so far. I'm using Vue 3.
My intention is to:
- Create a select with the items in the array as options, this works.
- Once the button is clicked, store the value of the select, this also works.
- Push an object using the value of the select as an object's key's value
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
CodePudding user response:
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>
CodePudding user response:
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.
CodePudding user response:
Someone made an answer but it was deleted, changing the method 'getGeneMutationData' from:
getGeneMutationData: () => {
to getGeneMutationData: function () {
solved it.