tsquared
tsquared

Reputation: 99

Cannot set property '_onButtonClick' of null with Polymer Neon Animations

I'm pretty new to Polymer and JS, but I've been trying to get used to both. Using this demo as a base, I've been trying to attach a scale-down animation to some icons using Neon Animations and a button click event. Whenever I try to use querySelector to find the template containing the button, it always returns:

"icon-toggle-demo.html:34 Uncaught TypeError: Cannot set property '_onButtonClick' of null"

No matter what I change I just can't get the button to not be null. I'm not sure what I'm missing here.

My file containing the button:

<link rel="import" href="../../polymer/polymer.html">
<link rel="import" href="../../iron-icons/iron-icons.html">
<link rel="import" href="../icon-toggle.html">


<dom-module id="icon-toggle-demo">
    <template is="dom-bind">
        <style>
            :host {
                font-family: sans-serif;
            }

            ;
        </style>

        <h3>Statically-configured icon-toggles</h3>
        <button on-click="_onButtonClick">click me</button>
        <icon-toggle toggle-icon="star"></icon-toggle>
        <icon-toggle toggle-icon="star" pressed></icon-toggle>

        <h3>Data-bound icon-toggle</h3>

        <!-- use a computed binding to generate the message -->
        <div><span>[[message(isFav)]]</span></div>


        <!-- curly brackets ({{}}} allow two-way binding -->
        <icon-toggle toggle-icon="favorite" pressed="{{isFav}}"></icon-toggle>
    </template>

    <script>
        var scope = document.querySelector('template[is="dom-bind"]');

        scope._onButtonClick = function(event) {
            var node = document.querySelector('toggle-icon');
            if (node) {
                node.animate();
            }
        };
    </script>

</dom-module>

Upvotes: 1

Views: 244

Answers (1)

tony19
tony19

Reputation: 138336

  • dom-bind templates are only needed in index.html. In a <dom-module>, you can just use a plain <template>.

  • To register your element, you'll need to use the Polymer function with a prototype object that has your _onButtonClick function like this:

    Polymer({
      is: 'icon-toggle-demo',
      _onButtonClick: function() {
        ...
      }
    });
    
  • Auto-node finding allows you to quickly access a node by ID with this.$.NODE_ID (e.g., this.$.myIcon). So, if your <icon-toggle> had an ID of "starIcon":

    ...you could access it from your Polymer object with this.$.starIcon:

    _onButtonClick: function() {
      this.$.starIcon.animate();
    }
    

Your full element definition would look something like this:

<dom-module id="icon-toggle-demo">
  <template>
    <style>
      :host {
        font-family: sans-serif;
      }
    </style>

    <h3>Statically-configured icon-toggles</h3>
    <button on-click="_onButtonClick">click me</button>
    <icon-toggle id="starIcon" toggle-icon="star"></icon-toggle>
    <icon-toggle toggle-icon="star" pressed></icon-toggle>

    <h3>Data-bound icon-toggle</h3>

    <!-- use a computed binding to generate the message -->
    <div><span>[[message(isFav)]]</span></div>

    <!-- curly brackets ({{}}} allow two-way binding -->
    <icon-toggle toggle-icon="favorite" pressed="{{isFav}}"></icon-toggle>
  </template>

  <script>
    Polymer({
      is: 'icon-toggle-demo',
      _onButtonClick: function() {
        this.$.starIcon.animate();
      }
    });
  </script>
</dom-module>

Upvotes: 1

Related Questions