Search code examples
polymerpolymer-1.0private-members

What is the best practices with declaring custom element's private property in Polymer


By looking at the Polymer dev guide, the properties declared within the properties object would become the element's public API. So I usually don't declare private properties inside of the properties object, but do

ready: function() {
  this.privatePropertyName = 'random text';
}

I've also seen some code declare private properties in properties with '_' prefix naming convention, like

  properties: {
    _privateProperty: {
      type: Number,
      readOnly: true,
      value: 0,
    }
  }

What is the best practices on this if any? Shall we try to stick with the rule that only public properties go into the properties object?


Solution

  • If you look at code developed by Polymer team the practice that they follow is to declare all the properties inside property object. They use _ to separate private properties from public.

    <link rel="import" href="https://polygit.org/components/polymer/polymer.html">
    <dom-module id="has-private">
      <template>{{newProp}}</template>
    </dom-module>
    <script>
      Polymer({
        is: 'has-private',
        properties: {
          _private: 'privateMember',
          inSide: {
            type: String,
            value: 'ousidePropertiesObject',
            reflectToAttribute: true,
            observer: '_insideChanged'
          }
        },
        outSide: {
          type: String,
          value: 'ousidePropertiesObject',
          reflectToAttribute: true,
          observer: '_changed'
        },
    
        _changed: function(newVal) {
          alert("New value if outSide is: " + newVal);
        },
    
        _insideChanged: function(newVal) {
          alert("New value if inSide is: " + newVal);
        },
    
        attached: function() {
          console.log("value of outSide", this.outSide);
          alert("From internal element \n outside: " + this.outSide + " inside: " + this.inSide);
          alert("New Prop: " + this.newProp);
          this.undeclaredProperty = "i'm not declared anywhere in the code";
        }
      })
    </script>
    
    
    <dom-module id="access-private">
      <template>
        <has-private id="private" out-side="doesn't matter" in-side="doesn't matter" new-prop="hello"></has-private>
      </template>
    </dom-module>
    <script>
      Polymer({
        is: 'access-private',
        attached: function() {
          this.$.private.outSide = "i work";
          this.$.private.inSide = "i work";
          alert("value of has-private element's private property in access private is: " + this.$.private._private);
          alert("value of property outside properties object is: " + this.$.private.outSide);
          alert("value of undeclared property is: " + this.$.private.undeclaredProperty);
        }
      })
    </script>
    
    
    <access-private>
      </access-private

    Here are few pointers regarding the properties.

    • It is not necessary to declare a public properties Object.
    • The property not declared in properties Object can still be public property i.e. it can be accessed by other elements.
    • Similarly, you can mention a attribute in markup that has not been declared in properties object and then use it in internal element's markup or javascript(except for Boolean).
    • One advantage of declaring in properties object is that it becomes easier to keep track of all your properties.
    • It also might have some impact on deserialisation which happens for properties declared in properties object.

    Adding a property to the properties object allows a user to configure the property from markup (see attribute deserialization for details). Any property that's part of your element's public API should be declared in the properties object.

    As you can see, Polymer documentation says property should be declared inside properties Object and not has to be or needs to be which means it is highly recommended rather then being mandatory