Search code examples
javascriptarrayspolymersplicehtml5-template

Polymer 1.0 array splice is deleting the wrong item in array


I am trying to create a simple to do list in Polymer, and I have the add portion working. When I click the "delete" icon next to the item, it deletes the most recently added item instead of the one that it should delete. It looks like it's getting the wrong index of the array, and I'm not sure how to fix it? Thanks!

<dom-module id="my-todo-list">
<template>

<div class="card">

  <div class="form">
    <paper-input label="Task" value="{{todo.task}}"></paper-input>
    <paper-button raised on-tap="_addTodo">Add Todo</paper-button>
  </div>

  <template is="dom-repeat" items="{{todos}}">
    <paper-card class="todos">
      <paper-checkbox id="checkTodo" on-click="_completeTodo"></paper-checkbox>
      <p>{{item.task}}</p>
      <iron-icon icon="delete" on-tap="_destroyAction"></iron-icon>
    </paper-card>
  </template>

</div>

</template>

<script>
Polymer({
  is: 'my-todo-list',

  properties: {
    todo: {
      type: Object,
      value: function() {
        return {};
      }
    },
    todos: {
      type: Array,
      value: function() {
        return [];
      }
    }
  },

  _addTodo: function() {
    console.log(this.todo);
    this.push('todos', this.todo);
    // this.todo = {};
  },

  _destroyAction: function(todo) {
    var index = this.todos.indexOf(todo);
    this.splice('todos', index, 1);
  },
});
 </script>
</dom-module>

Solution

  • The first issue is that you always insert the same reference to the object this.todo in your _addTodo() method. Instead you should make a copy of the object. You sould also add an ID to differentiate it from the other items.

      _addTodo: function() {
        var copy = Object.assign({}, this.todo);    
        copy.id = this.push('todos', copy);
        // this.todo = {};
      }
    

    Then you sould add the same ID in the HTML template:

    <paper-card class="todos" id="{{item.id}}">
    

    Now you can modify the _destroyAction() method to find the right element in the array, using Array.findIndex() method and Event.target property:

      _destroyAction: function(ev) {
        var index = this.todos.findIndex( function(item) { 
            return item.id == ev.target.parentElement.id 
        } );
        this.splice('todos', index, 1);
      }