I have an app with a custom input component where I'm trying to emit the change events up to the parent on save and send those values to the $store via commit/dispatch. I got confirmation that the parent can receive the values when I was debugging the component earlier (was retrieving the same values originally generated from the randomizer in this app, and confused as to why I'm getting this error:
[Vue warn]: Error in v-on handler: "TypeError: Cannot read properties of undefined (reading 'value')"
found in
---> <CustomInput>
It only shows up when a user is trying to type a new title/subtitle when editing them manually and shows up after each keystroke. Is this a timing error??
Custom Input:
<template>
<div>
<label for="title">Edit Title: </label>
<input
type="text"
id="title"
:updateTitle="updateTitle"
v-model="inputTitle"
/>
<label for="title">Edit Subtitle: </label>
<input
type="text"
id="subtitle"
:updateSubtitle="updateSubtitle"
v-model="inputSubtitle"
/>
</div>
</template>
<script>
export default {
name: 'CustomInput',
props: {
value: {
type: Object,
required: true,
},
},
computed: {
updateTitle() {
console.log('updateTitle: ', this.value.title);
return this.value.title;
},
updateSubtitle() {
console.log('updateSubtitle: ', this.value.subtitle);
return this.value.subtitle;
},
inputTitle: {
get() {
return this.value.title;
},
set(title) {
console.log('setting new title: ', title);
this.$emit('input', title);
},
},
inputSubtitle: {
get() {
return this.value.subtitle;
},
set(subtitle) {
console.log('setting new subtitle: ', subtitle);
this.$emit('input', subtitle);
},
},
},
};
</script>
Parent:
<template>
<main >
<div v-if="!editMode" >
<div >
<span >Title: </span>{{title}}
</div>
<div >
<span >Subtitle: </span>{{subtitle}}
</div>
<div >
<button id="randomize-button" @click="randomizeTitleAndSubtitle">
Randomize
</button>
<button id="edit-button" @click="onEdit">Edit</button>
</div>
</div>
<div v-else >
<CustomInput
:value="{ title, subtitle }"
@input="onSave(v = { title, subtitle }, $event.target.value)"
/>
<div >
<button id="cancel-button" @click="onCancel">Cancel</button>
<button id="save-button" @click="onSave">Save</button>
</div>
</div>
</main>
</template>
<script>
import CustomInput from '@/components/CustomInput.vue';
import { mapState, mapActions } from 'vuex';
export default {
name: 'Home',
components: {
CustomInput,
},
data() {
return {
editMode: false,
};
},
computed: {
...mapState(['title', 'subtitle']),
},
methods: {
...mapActions(['randomizeTitleAndSubtitle', 'updateTitleAndSubtitle']),
onEdit() {
this.editMode = true;
},
onCancel() {
this.editMode = false;
},
onSave(v) {
this.editMode = false;
console.log('returned value object: ', v);
this.$store.dispatch('UPDATE_TITLE', v.title);
this.$store.dispatch('UPDATE_SUBTITE', v.subtitle);
},
},
mounted() {
this.randomizeTitleAndSubtitle();
},
};
</script>
CodePudding user response:
The error points to the @input
:
<CustomInput
:value="{ title, subtitle }" ❌
@input="onSave(v = { title, subtitle }, $event.target.value)"
/>
CustomInput
emits the input
event with a string:
export default {
⋮
computed: {
⋮
inputTitle: {
⋮
set(title) {