/ WhatILearned

Two Way Data Binding Arrays in Polymer

One of the things that I loved with Angular 1 (and probably used a bit too much) was two-way data binding. Data-binding is the way to share data with multiple things but with synchronization.

With polymer when you're data-binding arrays you must use the array mutation methods. The temptation is to simply use the methods on the array itself like:

this.myArray.push(new_array_item);

And if you check this.myArray, you'll notice that it does indeed have a new item pushed to it but anything that was bound to myArray will not have the changes.

To send the proper events and fire the observers looking for change in two-way data binding you have to do the following:

this.push('myArray', new_array_item);

This will cause the changes in myArray to be reflected with all the other ones.

More on Data Binding

For example if I have a two objects (or elements in the case of Polymer) and one is modifying some internal variable, you would use data binding so that the changes done to the variable in the first object are automatically synchronized with the matching variable in the second object.

Starting Scenario say you have two elements

<fruit_basket>
   //has an array named myfruits
<fruit_basket>

<fruit_bowl>
   //has an array named myfruits
<fruit_bowl>

And you want to synchronize the array of fruits, the first thing to do is to bind them together

<fruit_basket myfruits="arrayOfFruits">
   //has an array named myfruits
<fruit_basket>

<fruit_bowl myfruits="arrayOfFruits">
   //has an array named myfruits
<fruit_bowl>

Now fruit_basket and fruit_bowl are linked, if changes are made to arrayOfFruits then myfruits will automatically change.

But what if you're inside one of the elements like fruit_bowl and you want changes to be pushed/reflected in fruit_basket?

<fruit_basket myfruits="arrayOfFruits">
   //has an array named myfruits
<fruit_basket>

<fruit_bowl myfruits="arrayOfFruits">
   //has an array named myfruits
   function someEvent() {
       //Assume newFruit is populated
       this.push('myfruits', newFruit);
    }
<fruit_bowl>

There are other methods you can use like

push(path, item1, [..., itemN])
pop(path)
unshift(path, item1, [..., itemN])
shift(path)
splice(path, index, removeCount, [item1, ..., itemN])

There are two important things to note about data binding arrays

  1. Changes to array are done via the this.method() notation not the this.arrayVariableName.method() . If you do the latter, only the local array will be changed and nothing will be synced.
  2. The this.method requires a path, but this is referencing the local variable/member not the "external" one (e.g. should be this.push('myfruits') not this.push('arrayOfFruits')