Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 + Ionic 2 + Barcode Scanner DOM not updating on binding change

I'm stuck trying to access a binding from within a success function. This is the code as I have it:

import {Page, Platform, Modal, NavController, NavParams, ViewController} from 'ionic-angular';
import {Component, Input} from 'angular2/core';

@Page({
  templateUrl: 'build/pages/addModal/addModal.html',
  directives: []
})

export class addModal {
  public barcode: String = '';

  static get parameters() {
    return [[ViewController], [Platform]];
  }

  constructor(public _viewCtrl: ViewController, _platform: Platform){
    var category = "Grocery";
    this.barcode = '';

    _platform.ready().then(() => {

      this.openScanner();

    });
  }

  openScanner() {
    cordova.plugins.barcodeScanner.scan(
        (result) => {
          console.log('DEBUG || Barcode scanned: ' + result.text);
          this.barcode = result.text;
        }, 
        (error) => {
            alert("Scanning failed: " + error);
        }
      );
  }

  close() {
    this._viewCtrl.dismiss();
  }
}

When the scanner has scanned it should be updating the variable 'barcode' to the barcode scanned. I know the scanner is working because it logs the output successfully.

The issue is the DOM isn't updating at all. The HTML template is:

    <ion-item>
      <ion-label fixed>Barcode</ion-label>
      <ion-input type="text" placeholder="eg. 5058937528594" [value]="barcode" (input)="barcode=$event.target.value"></ion-input>
      <button (click)="openScanner()" outline item-right>
        <ion-icon name="qr-scanner"></ion-icon>
      </button>
    </ion-item>

I have also tried using:

<ion-input type="text" placeholder="eg. 5058937528594" [value]="barcode"></ion-input>

<ion-input type="text" placeholder="eg. 5058937528594" [(ngmodel)]="barcode"></ion-input>

<ion-input type="text" placeholder="eg. 5058937528594" #barcode></ion-input>

Also tried to wrap in a timeout function as some people have said that it could be an Angular bug. So tried:

setTimeout(() => this.barcode = result.text, 1);

Without any success. There is no error message displayed and I believe that from debugging in safari dev console that "this" is referenced correctly and accessible (using a device not in the browser. I know cordova doesn't work on a PC browser!).

Edit: So after calling console.log(this.barcode); immediately after this.barcode = result.text; I've found out that it's not updating the variable? Why would this be?

Edit 2: So now it is updating. It doesn't update if I wrap it in a timeout function so I'm guessing that it's not updating the original variable from within the success function?

like image 377
Alex Bailey Avatar asked Mar 10 '16 21:03

Alex Bailey


1 Answers

Ensure the assignment runs in Angulars zone:

import {Component, Input} from 'angular2/core';

...

constructor(public _viewCtrl: ViewController, _platform: Platform, private zone:NgZone){ ... }

...
this.zone.run(() => this.barcode = result.text;);

See also

  • https://angular.io/docs/ts/latest/api/core/NgZone-class.html
  • Triggering Angular2 change detection manually
like image 65
Günter Zöchbauer Avatar answered Sep 28 '22 14:09

Günter Zöchbauer