Search code examples
javascriptpolymerweb-component

When in a Polymer component's life cycle are changed watchers fired for declaratively-specified values?


From the Polymer docs, the life cycle for most callbacks is clear:

 created -> ready -> attached -> domReady
    ^                               |
    |                               |
     ---------- detached <----------

And I imagine attributeChanged() will be fired at any point in this lifecycle when an attribute is modified, e.g. even as early as when created:

created: function() {
  this.attribute = 'newValue';
}

But what if an instance of my element is provided a value declaratively?

<my-element attribute="newValue"></my-element>

When in the element life cycle are attribute changed watchers fired in this case?


Solution

  • Not 100% I understand what you mean, but using a simple test it turns out that the attributeChanged event is called after attached and before domReady. The attribute value however is already readable from ready onwards. This is easy to understand, because the attributeChanged event is called from a javascript callback function and the same applies for the domReady event, however they don't trigger straight away as the code is already running.

    If you set the value in the created event it will not in any way be reflected (except of course in the function itself where you assigned it). Attributes are handled after the created event, but before the ready event.


    If you want to see this for yourself:

    <my-element myAttribute="attributeValue"></my-element>
    

    and the element itself is defined as

    <polymer-element name="my-element" attributes="myAttribute">
      <template>
        <span>Hello from <b>my-element</b>. This is my Shadow DOM.</span>
      </template>
      <script>
        Polymer({
          created: function() {
            //has no effect on the element:
            //this.myAttribute = "newValue";
    
            console.log("created", this.myAttribute);
          },          
          ready: function() {
            //works fine:
            //this.myAttribute = "newValue";
    
            console.log("ready", this.myAttribute);
          },
          attached: function() {
            console.log("attached", this.myAttribute);
          },
          domReady: function() {
            console.log("domReady", this.myAttribute);
          },
          myAttributeChanged: function() {
            console.log("myAttributeChanged", this.myAttribute);
          }
        });
      </script>
    </polymer-element>