I am trying to make a form repeater using an array and Vue v-for loop. but I could not able to push or slice anything in my array. I got some warning. TypeError: Cannot read property 'items' of undefined
Here is my code
<template>
<b-form @submit.prevent="repeateAgain">
<b-row
v-for="(item, index) in items"
:id="item.id"
:key="item.id"
>
<b-col>
<b-form-group>
<b-form-input
placeholder="Email"
/>
</b-form-group>
</b-col>
<b-col>
<b-form-group>
<b-form-input placeholder="Email" />
</b-form-group>
</b-col>
<b-col>
<b-form-group>
<b-form-input placeholder="Email" />
</b-form-group>
</b-col>
<b-col>
<b-form-group>
<b-button
variant="outline-danger"
@click="removeItem(index)"
>
<i class="feather icon-x" />
<span class="ml-25">Delete</span>
</b-button>
</b-form-group>
</b-col>
</b-row>
<hr>
<b-form-group>
<b-button
variant="primary"
@click="repeateAgain"
>
<i class="feather icon-plus" />
<span class="ml-25">Add</span>
</b-button>
</b-form-group>
</b-form>
</template>
<script>
import {
BForm, BFormGroup, BFormInput, BRow, BCol, BButton,
} from 'bootstrap-vue'
export default {
components: {
BForm,
BRow,
BCol,
BButton,
BFormGroup,
BFormInput,
},
data: () => ({
items: [{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'What to do ?',
}],
newTodoText: '',
nextTodoId: 2,
}),
methods: {
repeateAgain: () => {
this.items.push({
id: this.nextTodoId += +this.nextTodoId,
title: this.newTodoText,
})
this.newTodoText = ''
},
removeItem: index => {
this.items.splice(1)
console.log(index)
},
},
}
</script>
I also try to delete a particular row using the slice method but it not work. What am I forgetting??
You shouldn’t use arrow functions for data
or methods
in Vue, because arrow functions have their own context (this
)
repeateAgain: () => {
this.items.push({
In an occasion when repeateAgain
method is called, this
context is undefined - that’s why the error occurs ** TypeError: Cannot read property 'items' of undefined (this)**
You should modify it like this:
repeateAgain() {
this.items.push({
@submit.prevent="repeateAgain"
- this is what I meant by “occasion”. Since the method is not bound to the methods: {
object, but bound to relative context (none here - undefined) on the other hand, if it’s within a class, the class instance would be the context.
E.g: (only for demonstration, do not use this pattern)
In the following example,this
context is an instance of MyWrappedCmp
import {
BForm, BFormGroup, BFormInput, BRow, BCol, BButton,
} from 'bootstrap-vue'
class MyWrappedCmp {
getComponent(){
return {
methods: {
repeateAgain: () => {
// “this” context is an instance of MyWrappedCmp
// ...
}
}
}
}
const myWrapped = new MyWrappedCmp()
export default myWrapped.getComponent()