I am trying to create sensorArray
dynamically in my VueJS application. For this when I create an element and delete it and then when I try to create a new one then I get the following error:
client.js:227 TypeError: Cannot read properties of undefined (reading 'value')
at eval (templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./pages/Test.vue?vue&type=template&id=cde3d4aa&:44)
at Proxy.renderList (vue.runtime.esm.js:2643)
Following is the simple Vuejs application I have:
<template>
<div>
<span>Sensor Information : </span>
<button class="btn btn-info" @click="addSensorInfo($event)">
Add Sensor
</button>
<br>
<span v-if="sensorArray.length > 0"><b>Sensor Element: </b></span>
<span v-if="sensorArray.length > 0">
<div v-for="sensor in sensorArray" :key="sensor.ID" class="form-group">
<label class="form-label">Value</label>
<input v-model="sensorArray[sensor.ID].value" type="text" class="form-control">
<button class="btn btn-danger" @click="deleteSensorInfo($event,sensor.ID)"><i class="bi bi-trash" /></button>
</div>
</span>
</div>
</template>
<script>
export default {
data () {
return {
sensorID: 0,
sensorArray: []
}
},
methods: {
addSensorInfo (event) {
event.preventDefault()
const sensor = {}
sensor.ID = this.sensorID
this.sensorArray.push(sensor)
this.sensorID
},
deleteSensorInfo (event, sensorID) {
event.preventDefault()
this.sensorArray.splice(this.sensorArray.filter(obj => obj.ID === sensorID), 1)
}
}
}
</script>
- Click on
Add Sensor
button: A text field and delete button will appear. - Click on
Delete ICON
and delete the field. - Now again click on
Add Sensor
then I get following error:
client.js:227 TypeError: Cannot read properties of undefined (reading 'value')
Since I have a lot of elements within my SensorArray
I am not creating the dedicated element and trying to create everything dynamically based on user click. Can someone please let me know how can I fix this issue?
CodePudding user response:
First Error
This is not a valid JavaScript operation
this.sensorArray.splice(this.sensorArray.filter(obj => obj.ID === sensorID), 1)
Splice signature expects a number at first position
splice(start: number, deleteCount: number)
Filter signature returns an array.
Solution
const idx = this.sensorArray.findIndex(obj => obj.ID === sensorID);
if (idx !== -1) {
this.sensorArray.splice(idx, 1)
}
Or as mentioned you can use a more concise form
this.sensorArray = this.sensorArray.filter(obj => obj.ID === sensorID);
Second Error
Now I noticed that you are performing a strange array access. An array is indexed by id
not by your custom sensor.ID
, so this sensorArray[sensor.ID].value
makes no sense. It works before a delete by pure chance (due to how you are generating IDs).
This should be your code (note the v-model="sensor.value"
):
<div v-for="sensor in sensorArray" :key="sensor.ID" class="form-group">
<label class="form-label">Value</label>
<input v-model="sensor.value" type="text" class="form-control">
<button class="btn btn-danger" @click="deleteSensorInfo($event,sensor.ID)"><i class="bi bi-trash" /></button>
</div>
Furthermore .value
is never set.
CodePudding user response:
You are mixing up splice and filter
, to delete the item.
Simply use filter.
this.sensorArray = this.sensorArray.filter(obj => obj.ID === sensorID);