0

I have a component that is using the cordova BLE plugin. When the scan starts to find devices it pushes each device found to an array of objects. In my template I use *ngFor to loop through the objects but the template is not updating and showing the list of devices even though if I console.log(deviceList) I can see it populated. The array is called deviceList

bluetooth.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Observable, Subscription } from 'rxjs/Rx';
import { BLE } from '@ionic-native/ble';


@Component({
selector: 'bluetooth',
templateUrl:'bluetooth.html'
})
export class Bluetooth {

/* new */
showWizard = true;
buttonConnected = false;
step = "BLEStepOne";
deviceList = [];

  constructor(public ble: BLE) {
}

ionViewDidLoad() {
  this.scanForDevices();
}

hideWizardCMD(){
    this.showWizard = false;
}

showWizardCMD(){
    this.showWizard = true;
}

gotoStep(step){
    this.step = step;
    if(step == "BLEStepTwo"){
        console.log('ble scan start');
        this.scanForDevices();
    }
}

scanForDevices(){
  console.log("scan for devices");
  this.deviceList = [];
  this.ble.startScan([]).subscribe(device => {
    this.deviceList.push(device);
    console.log(this.deviceList);
  });
}

}

bluetooth.html

<div class="not-logged-in" *ngIf="step=='BLEStepOne' && !buttonConnected">
<h2 class="smaller">Claim your Bel</h2> 
<p>Click to wake the button</p>
<img class="button-image" src="assets/images/button.png" />
<div class="buttons">
    <a class="btn btn-lg blank" (click)="hideWizardCMD()" href="#" >Skip</a> 
    <a class="btn btn-lg" (click)="gotoStep('BLEStepTwo')" href="#">Next</a> 
</div>
</div>

<div class="not-logged-in" *ngIf="step=='BLEStepTwo' && !buttonConnected">
<h2 class="smaller">Claim your Bel</h2> 
<p>Select your button to claim</p>
<ion-list>
  <ion-item *ngFor="let device of deviceList">
    <ion-label>{{device.id}}</ion-label>
    <ion-toggle [(ngModel)]="device.connected" (ngModelChange)="toggleConnection($event,device)"></ion-toggle>
  </ion-item>
</ion-list>
<div class="buttons">
    <a class="btn btn-lg" (click)="gotoStep('BLEStepOne')" href="#">Back</a> 
    <a class="btn btn-lg" (click)="gotoStep('BLEStepOne')" href="#">Claim</a> 
</div>
</div>
Jamie Barker
  • 163
  • 1
  • 15
  • The deviceList is been updated in a subscription, which is an asynchronous call. so the code looks good AFAIK. Maybe you can try importing `ChangeDetectionRef`, and manually trigger change detection by calling `detectChanges()` method. – Brian Li Apr 06 '18 at 04:19

2 Answers2

0

Implements onChanges is missing for component apply that

niteshbisht
  • 179
  • 8
0

I think the correct way was to use NgZone.

import { Component, NgZone } from '@angular/core';

then:

constructor(public ble: BLE, private zone: NgZone) {
}

scanForDevices(){
  this.deviceList = [];
  this.ble.startScan([]).subscribe(device => {
    this.zone.run(() => {
      this.deviceList.push(device);
    });
  });
}
Jamie Barker
  • 163
  • 1
  • 15