Search code examples
data-bindingpolymerpolymer-2.x

Polymer 2.0 Data Binding not working


I have an view in Polymer whereby users can scan a QR code and the data will appear as a heading below the video preview. This is the code.

<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="shared-styles.html">
<script type="text/javascript" src="../js/instascan.min.js"></script>

<dom-module id="my-view1">
  <template>
    <style>
      :host {
        display: block;
        text-align: center;
      }

      #preview {
        width: 100% !important;
        height: auto !important;
        border-radius: 2px;
      }
    </style>
    <!-- Video preview of camera for QR code scanning -->
    <video id="preview"></video>
    <!-- List of QR code items scanned-->
    <h1>{{bucketItems}}</h1>
  </template>
  <script>
    class MyView1 extends Polymer.Element {
      static get is() { return 'my-view1'; }
      static get properties() {
        return {
          bucketItems: {
            type: String,
            reflectToAttribute: true
          },
        }
      }

      // Once page has loaded
      connectedCallback() {
        super.connectedCallback();
        // List of items in bucket (contains scanned ingredients)
        var itemsBucket = [];
        // Scan QR Code using Instascanner
        let scanner = new Instascan.Scanner({ video: this.$.preview });
        scanner.addListener('scan', function (content) {
          // Access the QR code content using "content"
          if (!itemsBucket.includes(content)) {
            // Only add items once to the bucket
            itemsBucket.push(content);
          }
          this.bucketItems = itemsBucket.toString();
          console.log(this.bucketItems);
        });
        Instascan.Camera.getCameras().then(function (cameras) {
          if (cameras.length > 0) {
            scanner.start(cameras[0]);
          } else {
            console.error('No cameras found.');
          }
        }).catch(function (e) {
          console.error(e);
        });
      }
    }
    window.customElements.define(MyView1.is, MyView1);
  </script>
</dom-module>

When I console.log(this.bucketItems) I can see the list of items they have scanned but the data is not visible in the h1 tag. How do I bind it correctly. I am new to polymer and just beginning to learn data bindings.


Solution

  • This problem is the context of your callback is not bound to the Polymer object, so it uses the outer context.

    You could switch to arrow functions to automatically bind the Polymer object, use :

    scanner.addListener('scan', content=> {
    

    instead of:

    scanner.addListener('scan', function (content) {
    

    DEMO