polymer-2.xdom-repeat

polymer 2 dom-repeat does not reflect when item is removed


I have a very simple application in Polymer 2. I have a static list of items which is displayed with dom-repeat. I have a button for delete, on click i could see the item is removed from the list. But the dom-repeat is not refreshed. Its still the old code.

Can someone help how to reflect the changes on the screen:

code snippet is below:

<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/iron-list/iron-list.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../../bower_components/app-storage/app-localstorage/app-localstorage-document.html">
<link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html">

<dom-module id="todo-list">
    <template>
        <style>
             :host {
                display: block;
            }

            .ibtn {
                float: right;
            }

            .item {
                width: 500px;
            }

            paper-icon-button {
                color: grey;
            }

            .list-todo {
                height: 700px;
                text-align: left;
                -webkit-text-fill-color: brown;
            }

            .list-todo ul li {
                width: 500px;
                font-family: sans-serif;
                font-size: 20px;
            }

            .list-todo .btn-set {
                float: right;
            }
        </style>


        <!-- <app-localstorage-document key="app-store" data="{{todos}}"></app-localstorage-document> -->

        <div class="list-todo">

            <template is="dom-repeat" items="{{todos}}">
                <ul>
                    <li>
                        <iron-icon icon="icons:arrow-forward"></iron-icon>
                        {{item}}
                        <span class="btn-set">
                            <paper-icon-button icon="create"></paper-icon-button>
                            <paper-icon-button icon="delete" on-tap="deleteTodo"></paper-icon-button>
                            <paper-icon-button icon="star"></paper-icon-button>
                        <span>  
                    </li>
                </ul>
            </template>   
    </div>
  </template>

  <script>
    /**
     * @customElement
     * @polymer
     */
    class TodoList extends Polymer.Element {

        static get is() { return 'todo-list'; }

        static get properties() {
            return {
                todos: {
                    type: Object,
                    value: ["Build the code", "Check Sonar Issues", "Release the APP", "Deploy in Production", "Get Feedback"],
                    notify: true
                }
            };
        }

        populateTodoList() {
            return this.todos;
        }

        deleteTodo(item) {
            this.todos.splice(item.model.index, 1);
            this.todos.flush;
        }
    }

    window.customElements.define(TodoList.is, TodoList);
</script>
</dom-module>

Solution

  • Javascript splice removes the item from the array, but it does not mean the change is reflected in polymer shadowRoot.

    To do this you have to use polymer array mutation methods. See this.

    In your case will be:

    this.splice('todos', item.model.index, 1);
    

    Also, this.todos.flush; is not needed.

    Another thing I detected (not related with this), are you sure you want to have <ul> inside the repeat? This created a bunch of list with just one item inside each list.

    I suggest you to do this

    <div class="list-todo">
          <ul>
            <template is="dom-repeat" items="{{todos}}">
                <li>
                    <iron-icon icon="icons:arrow-forward"></iron-icon>
                    {{item}}
                    <span class="btn-set">
                        <paper-icon-button icon="create">create</paper-icon-button>
                        <paper-icon-button icon="crystal-icons:lens" on-tap="deleteTodo">delete</paper-icon-button>
                        <paper-icon-button icon="star">star</paper-icon-button>
                    <span>
                </li>
            </template>
          </ul>
        </div>
    

    This way you just create one list.