naveen
naveen

Reputation: 937

Why index-of not working correctly in vuejs?

I make a custom component in Vue.js .In My component, I have a list which has a delete button.On click of a button, it deletes the row.If I click any row it deletes the last row because the index is always -1 why? here is my code https://plnkr.co/edit/hVQKk3Wl9DF3aNx0hs88?p=preview

 methods: {
        deleteTodo:function (item) {
            console.log(item)
            var index = this.items.indexOf(item);
            this.items.splice(index, 1);
        }
    }

below Whole code

var MyComponent = Vue.extend({
    template:'#todo-template',
    props:['items'],
    computed: {
        upperCase: function () {
            return this.items.map(function (item) {
                return {name: item.name.toUpperCase(),complete:item.complete};
            })
        }
    },
    methods: {
        deleteTodo:function (item) {
            console.log(item)
            var index = this.items.indexOf(item);
            this.items.splice(index, 1);
        }
    }
})
Vue.component('my-component', MyComponent)

var app = new Vue({
    el: '#App',
    data: {
        message: '',
        items: [{
            name: "test1",
            complete:true
        }, {
            name: "test2",
            complete:true
        }, {
            name: "test3",
            complete:true
        }]
    },
    methods: {
        addTodo: function () {
           this.items.push({
               name:this.message,
               complete:true
           });
           this.message ='';
        },
    },
    computed: {
        totalCount:function () {
            return this.items.length;
        }
    }
});

Upvotes: 0

Views: 4405

Answers (2)

Shubham Patel
Shubham Patel

Reputation: 3289

Instead of passing the whole object you should pass the index of the item.

Change the for loop to

 <li v-for="(item, index) in upperCase" v-bind:class="{'completed': item.complete}">
        {{item.name}}
        <button @click="deleteTodo(index)">X</button>
        <button @click="deleteTodo(index)">Toggle</button>
 </li>

and the delete function to

deleteTodo:function (itemIndex) {
    this.items.splice(itemIndex, 1);
}

Updated Code: Link

Upvotes: 1

Mikkel
Mikkel

Reputation: 7777

Your code is assuming that indexOf will return a valid index

    deleteTodo:function (item) {
        console.log(item)
        var index = this.items.indexOf(item);
        this.items.splice(index, 1);
    }

If it's returning -1, it means that it's not finding the item in the list. Quite likely this.items is not what you think it is.

A bit of defensive code will help you solve this:

    deleteTodo:function (item) {
        console.log(item)
        var index = this.items.indexOf(item);
        if (index === -1)
          console.error("Could not find item "+item in list: ",this.items);
        else
          this.items.splice(index, 1);
    }

This will show you what this.items is in your console output

Upvotes: 0

Related Questions