Search code examples
polymerweb-componentpolymer-2.x

Why does Webcomponent object value is shared between the different instances of the same webcomponent?


I created a web component called TestElement with Polymer as below. It simply has an object value and a function which adds values to this component.

<dom-module id="test-element">
  <template>Test Element</template>

  <script>
    class TestElement extends Polymer.Element {
    static get is() { return "test-element"; }

    static get properties() {
      return {
        _myVar: {
          type: Object,
          value: {},
        },
      };
    }

    addNew(key, val) {
      this._myVar[key] = val;
    }
  }

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

I created two instances of this in a parent element as follows:

class ParentElement extends Polymer.Element {
  static get is() { return "parent-element"; }

  ready() {
    super.ready();
    this.$.myElement.addNew('key1', 'val-1');
    this.$.myElement2.addNew('key2', 'val2'); 
    console.log(this.$.myElement._myVar); // Expected to have {'key1': 'val-1'} but got {'key1': 'val-1', 'key2': 'val2'}. Why?
  }
}

In the console log above, I expect to have {'key1': 'val-1'} but got {'key1': 'val-1', 'key2': 'val2'}. Why?

If you want to have a working example please refer to this plunkr:

http://plnkr.co/edit/7jSwTTBbBxD4qCbUoCGI?p=preview


Solution

  • JavaScript objects are by reference and when you define the default value it's a single object.

    static get properties() {
      return {
        _myVar: {
          type: Object,
          value: {},
        },
      };
    }
    

    To avoid this you can define a function that will return a new object for each component instance.

    static get properties() {
      return {
        _myVar: {
          type: Object,
          value: function() { return {}; },
        },
      };
    }