Let Me Tink About It
Let Me Tink About It

Reputation: 16132

Polymer 1.x: Deleting an item from iron-list

I am trying to delete an item from iron-list using the following code.

my-element.html
<iron-list id="list" items="[[items]]" as="item"
           selected-items="{{selectedItems}}"
           selection-enabled multi-selection>
  <template>
    <my-item item="[[item]]" on-tap="_onItemTap"></my-item>
  </template>
</iron-list>
...
_onItemTap: function(e) {
  this.items.splice(e.model.index, 1);
}

Expected behavior

  1. Tap list item
  2. List item disappears
  3. Select next list item
  4. Next list item is selected

Actual behavior

  1. Tap list item
  2. List item does not disappear
  3. Select same list item (i.e., the one previously intended to be deleted)
  4. Next list item is actually selected (i.e., index offset by one)

Questions

Upvotes: 2

Views: 1338

Answers (4)

Let Me Tink About It
Let Me Tink About It

Reputation: 16132

See this answer for specific syntax contributing to the problem.

Here is a working JSBin.

http://jsbin.com/qefemoloxi/1/edit?html,console,output
<!doctype html>
<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
  <link href="paper-button/paper-button.html" rel="import">
  <link href="iron-list/iron-list.html" rel="import">
</head>
<body>

<dom-module id="x-element">

<template>
  <style>
    iron-list {
      height: 100vh;
    }
  </style>
  <iron-list id="list" items="[[items]]" as="item">
    <template>
      <paper-button on-tap="_deleteItem">[[item.name]]</paper-button>
    </template>
  </iron-list>
</template>

<script>
  (function(){
    Polymer({
      is: "x-element",
      properties: {
        items: {
          type: Array,
          value: function() {
            return [
              { 'name':'foo' },
              { 'name':'bar' },
              { 'name':'qux' },
              { 'name':'baz' },
              { 'name':'quux'}
            ]
          }
        }
      },
      _deleteItem: function(e) {
        console.log(e.model.index);
        this.splice('items', e.model.index, 1);
        this.$.list.fire('resize');
      }
    });
  })();
</script>

</dom-module>

<x-element></x-element>

</body>

Upvotes: 2

Let Me Tink About It
Let Me Tink About It

Reputation: 16132

See this answer for full code solution.

The problem here was caused by the fact that my item.html file was setting and displaying properties outside the item. property. So, when the iron-list.(this.)splice('items', e.model.index, 1); array mutation method was called, the non item properties were not being removed from the DOM.

Example:

my-list-item.html
this.set(     'name', this.item.foo.bar.qux); // This syntax caused the problem
this.set('item.name', this.item.foo.bar.qux); // This fixed the problem
my-iron-list.html
this.splice('items', e.model.index, 1);

Upvotes: 0

Let Me Tink About It
Let Me Tink About It

Reputation: 16132

This documentation on array mutation provides the following boilerplate code:

custom-element.html
<dom-module id="custom-element">
  <template>
    <template is="dom-repeat"></template>
  </template>
  <script>
    Polymer({
      is: 'custom-element',
      addUser: function(user) {
        this.push('users', user);
      },
      removeUser: function(user) {
        var index = this.users.indexOf(user);
        this.splice('users', index, 1);
      }
    });
  </script>
</dom-module>

Applying that to this case:

my-element.html
// As a syntactical matter, replace the following line
// this.items.splice(e.model.index, 1);
// With this line
this.splice('items', e.model.index, 1);
this.$.list.fire('resize');

A problem with this solution, however, is that it deletes the last item from the iron-list, not the item at the expected index. In other words, it behaves like one would expect this.items.pop().

It also throws the following curious error message:

console.log
Uncaught TypeError: <item> should be a valid item

Upvotes: 0

Let Me Tink About It
Let Me Tink About It

Reputation: 16132

A summary of this page suggests this documentation as follows:

Question
app.removeItem = function(index) {
  app.data.splice(index, 1);
  console.log("Removing " + index);
  document.querySelector('#tobuy').fire('resize');
};
Reply

document.querySelector('#tobuy').push('items', {name: "Foo"})

then you don't need to call resize.

ref: https://www.polymer-project.org/1.0/docs/devguide/properties.html#array-observation

Upvotes: 0

Related Questions