Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue array.splice removing wrong item from list

I have a list and I am using a for loop to loop through it. The structure looks like this:

salesLists: { 
  1: [ [], [], [] ]
  2: [ [], [] ]
}

And html:

<div v-for="(saleLists, index) in salesLists">
    <my-comp v-for="(item, i) in saleLists" :key="i" :index="parseInt(i)+1"></my-comp>
</div>

Now, I am trying to remove items from salesLists[1] array. I have a button for that and @click="removeForm":

removeForm(e) {
        var index = parseInt(e.target.getAttribute('data-index')) - 1 // = 2
        var client = e.target.getAttribute('data-client')             // = 1
        //Vue.delete(this.salesLists[client], index);
        this.salesLists[client].splice(index, 1)
        this.$forceUpdate()
}

It removes it, however, as I didn't specify any keys and it's just empty arrays (i assume), it is not removing the right element from the DOM. It removes index of 2, but as it is v-for looping through the item, and count reduces, it only removes the last item in the end.

What is the proper way of overcome this issue? :/

Here is a Fiddle: https://jsfiddle.net/8rvfz40n/ try writing different values for each input field and removing the middle one, you'll see it will remove the last one

like image 937
senty Avatar asked Dec 10 '22 10:12

senty


1 Answers

<div v-for="(saleLists, index) in salesLists">
    <my-comp v-for="(item, i) in saleLists" :key="i" :index="parseInt(i)+1"></my-comp>
</div>

The use of the index as key is the problem, when you delete a item from the middle the index that is lost is the last.

In my case the solution that I found is add a unique "Hash" to the items, like an ID, but if the items are news, the ID is null.

The hash that I use is a timestamp:

Hash: new Date().getTime()

And then:

 <div v-for="(saleLists, index) in salesLists">
     <my-comp v-for="(item, i) in saleLists" :key="item.Hash" :index="parseInt(i)+1"></my-comp>
 </div>
like image 121
Maske Avatar answered Dec 23 '22 18:12

Maske