Tihomir
Tihomir

Reputation: 124

Event example from Polymer 3 devguide "Listener on outside elements" throws an exception

I've created example for the snippets from the Polymer 3 dev guide. This example doesn't compile as _myLocationListener is not defined and it is used in the constructor. The listener is also not defined inside the dev guide snippet.

How this._myLocationListener property should be initialized.

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

/**
 * @customElement
 * @polymer
 */
class XcustomElementEventHandlingApp extends PolymerElement {
    static get template() {
        return html`
      <style>
        :host {
          display: block;
          border: dotted;
          background: aliceblue;
        }
      </style>
      <h2>Hello [[prop1]]!</h2>
      <button on-click="handleClick">Kick Me</button>
      <div id="child-el-01">Please, check the logs in Console (dev tools).</div>
    `;
    }

    static get properties() {
        return {
            prop1: {
                type: String,
                value: 'xcustom-element-event-handling-app'
            }
        };
    }

    constructor() {
        super();

        this._boundListener = this._myLocationListener.bind(this);
    }

    ready() {
        super.ready();
        this.addEventListener('click', this._onClick);

        const childElement = this.shadowRoot.getElementById('child-el-01');
        childElement.addEventListener('click', this._onClick.bind(this));
        childElement.addEventListener('mouseover', event => this._onHover(event));


        console.log('(this, the) custom element added to DOM.');
    }

    handleClick() {
        console.log('Ow!');
    }

    _onClick(event) {
        this._makeCoffee();
    }

    _makeCoffee() {
        console.log('in _makeCoffee()')
    }

    _onHover(event) {
        console.log('_onHover(ev) called');
        console.log(JSON.stringify(event));
    }

    connectedCallback() {
        super.connectedCallback();
        window.addEventListener('hashchange', this._boundListener);
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        window.removeEventListener('hashchange', this._boundListener);
    }
}

window.customElements.define('xcustom-element-event-handling-app', XcustomElementEventHandlingApp);

package.json:

{
  "name": "xcustom-element-event-handling",
  "description": "event handling demo. From dev guide.",
  "dependencies": {
    "@polymer/polymer": "^3.0.0"
  },
  "devDependencies": {
    "@webcomponents/webcomponentsjs": "^2.0.0",
    "wct-browser-legacy": "^1.0.0"
  }
}

Following exception is thrown:

Uncaught TypeError: this._myLocationListener.bind is not a function
at new XcustomElementEventHandlingApp (xcustom-element-event-handling-app.js:36)

Upvotes: 2

Views: 795

Answers (2)

bloo
bloo

Reputation: 1560

just to improve on HakanC's solution from Polymer 3 documentation, I managed to combine the ideas of each method without overriding any callbacks and managed to come up with the following method that goes in the class definition and is called externally; similar to interfaces in JAVA.

  public setOnClickListener(method): void {
    const self = this;
    $(self).on('click', method.bind(self);
    //  or self.addEventListener('click', method.bind(self)); if you use typescript
  }

simple enough for me...:)

Upvotes: 0

Cappittall
Cappittall

Reputation: 3441

At the above example, the main idea is if you like to listen an event from outside of this custom element. You may set up a listener inside connectedCallback and remove it with disconnectedCallback, then assign a function in the element after event occure. Something like

index.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    <script type="module" src="x-custom.js"></script>
  </head>
  <body>
    <button>This button not in the element</button>
    <x-custom></x-custom>
  </body>
</html>

x-custom.js:

import { PolymerElement, html } from 'https://unpkg.com/@polymer/[email protected]/polymer-element.js';

class XCustom extends PolymerElement {
  static get template() {
        return html`<h2>Hello </h2> `;
  }

    constructor() {
        super();
        this._boundListener = this._myLocationListener.bind(this);
    }

    connectedCallback() {
        super.connectedCallback();
        window.addEventListener('click', this._boundListener);
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        window.removeEventListener('click', this._boundListener);
    }
    _myLocationListener(){
        alert('This click comes from index.html - out of this element')
    }
}

window.customElements.define('x-custom', XCustom);

DEMO

Upvotes: 2

Related Questions