Tyler Graf
Tyler Graf

Reputation: 454

Polymer - Set Array Not Updating DOM

I'm trying to use a unidirectional data flow with polymer. So I'm updating the store outside of polymer and then firing events when it has been updated. When I set the array the first time, it works. But subsequent times it does not work.

Here's a pen: http://codepen.io/tylergraf/pen/EyXZva/

Here's the code:

<base href="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/">

<script src="webcomponentsjs/webcomponents-lite.min.js"></script>

<link rel="import" href="iron-icon/iron-icon.html">
<script>
window.theList = [{
  stuff: 'stuff'
}];
</script>
<button id="changeOutside">Increment Value</button>
<parent-element></parent-element>

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

  <template>
    <div class="list">
      <template is="dom-repeat" items="[[list]]">
        <child-element item="[[item]]"></child-element>
      </template>
    </div>
  </template>

  <script>
    Polymer({
      is: 'parent-element',
      ready: function(){

        document.addEventListener('dispatch', (e)=>{
          console.log(e.detail);
          // this.list = e.detail;
          this.set('list', e.detail);
        });

      }
    });
  </script>
</dom-module>

<dom-module id="child-element">
  <template>
    <ul>
      <li>Stuff: [[item.stuff]]</li>
    </ul>
  </template>

  <script>
    Polymer({
      is: 'child-element',
      properties: {
        item: {
          type: Object,
          value: {
            stuff: 'stuff',
            things: 'things'
          }
        },
      }
    });
  </script>
</dom-module>

<script>
var changeOutside = document.querySelector('#changeOutside');
var inc = 0;

changeOutside.addEventListener('click', function(){
  var newList = window.theList.map(function(li){
    li.stuff = inc++;
    return li;
  });
  var event = new CustomEvent('dispatch', {detail: newList});
  document.dispatchEvent(event);
})
</script>

Upvotes: 2

Views: 320

Answers (1)

Josh C.
Josh C.

Reputation: 390

There is definitely something weird going on here, The following is a workaround but I'd love to see Polymer support this.

Your issue there is that the return value in the map is a modified version of the existing object. The Object reference itself hasn't changed. So though there is a new Array being created from the map, the Object itself hasn't changed.

If you change this map

var newList = window.theList.map(function(li){
  li.stuff = inc++;
  return li;
});

to the following:

var newList = window.theList.map(function(li){
  return {
    stuff: inc++
  };
});

Then the code works as expected.

Upvotes: 1

Related Questions