Let Me Tink About It
Let Me Tink About It

Reputation: 16112

Polymer event handler

My Goal

My goal is to wrap the demo shown in this jsBin inside a Polymer custom element to implement the Google GeoChart API to create a selectable U.S. map.

What I expect to see...

When I open this jsBin and click on a state, I expect to see the selected item logged to the console.

What I actually see...

Instead, I see the following error:

Cannot read property 'getSelection' of undefined.

Attempted Solutions

Below, I have posted my original code. And my attempted solution. (The comments in each reflect the other attempt.)

In my attempted solution, I tried to persist the chart variable as a property. But that failed with the following error:

Cannot read property 'draw' of undefined at x-element.Polymer._drawRegionsMap

How do I get this to work?

Original code -- http://jsbin.com/zaqutegima/edit?html,console,output
<!doctype html>
<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

</head>
<body>

<dom-module id="x-element">

<template>
  <style>
    #geochart {
      width: 100%;
      max-height: 500px;
    }
  </style>
  <button on-tap="_show">Show</button>
  <div id="geochart"></div>
</template>

<script>
  (function(){
    Polymer({
      is: 'x-element',
      properties: {
        items: {
          type: Array,
          value: function() {
            return [['State', 'Select'], ['Alaska', 0], ['Alabama', 0], ['Arkansas', 0], ['Arizona', 0], ['California', 0], ['Colorado', 0], ['Connecticut', 0], ['Delaware', 0], ['Florida', 0], ['Georgia', 0], ['Hawaii', 0], ['Iowa', 0], ['Idaho', 0], ['Illinois', 0], ['Indiana', 0], ['Kansas', 0], ['Kentucky', 0], ['Louisiana', 0], ['Massachusetts', 0], ['Maryland', 0], ['Maine', 0], ['Michigan', 0], ['Minnesota', 0], ['Missouri', 0], ['Mississippi', 0], ['Montana', 0], ['North Carolina', 0], ['North Dakota', 0], ['Nebraska', 0], ['New Hampshire', 0], ['New Jersey', 0], ['New Mexico', 0], ['Nevada', 0], ['New York', 0], ['Ohio', 0], ['Oklahoma', 0], ['Oregon', 0], ['Pennsylvania', 0], ['Rhode Island', 0], ['South Carolina', 0], ['South Dakota', 0], ['Tennessee', 0], ['Texas', 0], ['Utah', 0], ['Virginia', 0], ['Vermont', 0], ['Washington', 0], ['Wisconsin', 0], ['West Virginia', 0], ['Wyoming', 0],];
          }
        },
        options: {
          type: Object,
          notify: true,
          value: {
            region: 'US',
            displayMode: 'regions',
            resolution: 'provinces',
            legend: 'none',
          }
        },
        /** /
        chart: {
          type: Object,
          notify: true,
          computed: '_computeChart()',
        },
        /**/
      },

      /** /
      _computeChart: function() {
        var out = new google.visualization.GeoChart(this.$.geochart);
        google.visualization.events.addListener(out, 'select', this._selectHandler);
        return out;
      },
      /**/

      get data() {
        return google.visualization.arrayToDataTable(this.items);
      },
       /**/
      get chart() {
        var out = new google.visualization.GeoChart(this.$.geochart);
        google.visualization.events.addListener(out, 'select', this._selectHandler);
        return out;
      },
      /**/

      ready: function(){
        google.charts.load('current', {
          'packages': ['geochart']
        });
        google.charts.setOnLoadCallback(this._drawRegionsMap.bind(this));
      },
      _drawRegionsMap: function() {
        this.chart.draw(this.data, this.options);
      },
      _selectHandler: function() {
        var selectedItem = this.chart.getSelection();
        console.log(selectedItem);
      },
      _show: function() {
        //console.log(this.items);
        //console.log(this.data);
        console.log(this.chart);
      },


    });
  })();

</script>

</dom-module>

<x-element></x-element>

</body>
Attempted solution -- http://jsbin.com/migefasuxe/edit?html,console,output
<!doctype html>
<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

</head>
<body>

<dom-module id="x-element">

<template>
  <style>
    #geochart {
      width: 100%;
      max-height: 500px;
    }
  </style>
  <button on-tap="_show">Show</button>
  <div id="geochart"></div>
</template>

<script>
  (function(){
    Polymer({
      is: 'x-element',
      properties: {
        items: {
          type: Array,
          value: function() {
            return [['State', 'Select'], ['Alaska', 0], ['Alabama', 0], ['Arkansas', 0], ['Arizona', 0], ['California', 0], ['Colorado', 0], ['Connecticut', 0], ['Delaware', 0], ['Florida', 0], ['Georgia', 0], ['Hawaii', 0], ['Iowa', 0], ['Idaho', 0], ['Illinois', 0], ['Indiana', 0], ['Kansas', 0], ['Kentucky', 0], ['Louisiana', 0], ['Massachusetts', 0], ['Maryland', 0], ['Maine', 0], ['Michigan', 0], ['Minnesota', 0], ['Missouri', 0], ['Mississippi', 0], ['Montana', 0], ['North Carolina', 0], ['North Dakota', 0], ['Nebraska', 0], ['New Hampshire', 0], ['New Jersey', 0], ['New Mexico', 0], ['Nevada', 0], ['New York', 0], ['Ohio', 0], ['Oklahoma', 0], ['Oregon', 0], ['Pennsylvania', 0], ['Rhode Island', 0], ['South Carolina', 0], ['South Dakota', 0], ['Tennessee', 0], ['Texas', 0], ['Utah', 0], ['Virginia', 0], ['Vermont', 0], ['Washington', 0], ['Wisconsin', 0], ['West Virginia', 0], ['Wyoming', 0],];
          }
        },
        options: {
          type: Object,
          notify: true,
          value: {
            region: 'US',
            displayMode: 'regions',
            resolution: 'provinces',
            legend: 'none',
          }
        },
        /**/
        chart: {
          type: Object,
          notify: true,
          computed: '_computeChart()',
        },
        /**/
      },

      _computeChart: function() {
        var out = new google.visualization.GeoChart(this.$.geochart);
        google.visualization.events.addListener(out, 'select', this._selectHandler);
        return out;
      },
      /**/

      get data() {
        return google.visualization.arrayToDataTable(this.items);
      },
       /** /
      get chart() {
        var out = new google.visualization.GeoChart(this.$.geochart);
        google.visualization.events.addListener(out, 'select', this._selectHandler);
        return out;
      },
      /**/

      ready: function(){
        google.charts.load('current', {
          'packages': ['geochart']
        });
        google.charts.setOnLoadCallback(this._drawRegionsMap.bind(this));
      },
      _drawRegionsMap: function() {
        this.chart.draw(this.data, this.options);
      },
      _selectHandler: function() {
        var selectedItem = this.chart.getSelection();
        console.log(selectedItem);
      },
      _show: function() {
        //console.log(this.items);
        //console.log(this.data);
        console.log(this.chart);
      },


    });
  })();

</script>

</dom-module>

<x-element></x-element>

</body>

Upvotes: 1

Views: 448

Answers (2)

Tim van der Lippe
Tim van der Lippe

Reputation: 768

The undefined error is due to a missing .bind(this) for this._selectHandler. The correct getter for chart therefore becomes:

  get chart() {
    var out = new google.visualization.GeoChart(this.$.geochart);
    google.visualization.events.addListener(out, 'select', this._selectHandler.bind(this));
    return out;
  },

Upvotes: 1

0Ds0
0Ds0

Reputation: 598

Maybe you should do it on the attached event with the async function Change your ready function to

attached: function(){
    this.async(function() {
        google.charts.load('current', {'packages': ['geochart']});
        google.charts.setOnLoadCallback(this._drawRegionsMap.bind(this));
    });
(..)

Upvotes: 1

Related Questions