Ionic newbie here. I'm using Ionic 3 and the BLE plugin. The way this plugin works is you start scanning for Bluetooth devices, you are notified with each new scan result, and then when you are done you cancel the scan. I'm just trying to append an element into an ion-list
each time a new scan result is received.
This Cordova plugin uses callbacks which ionic wraps into Observables and Promises. The method startScan
returns an Observable<any>
, and that "any" is an object containing info about a detected BLE device.
I first tried to plug this observable directly into the ngFor:
<ion-list>
<button ion-item *ngFor="let result of results | async">
{{ result | json}}
</button>
</ion-list>
The call to start scan returned the observable:
this.results = this.ble.startScan([]);
this.results.subscribe(...);
However I heard that ngFor
only works with arrays, so it would need an Observable<Array>
instead of an observable of a single object. So I ditched the Observable and used an array instead. The async pipe no longer worked so I had to modify the list:
<ion-list>
<button ion-item *ngFor="let result of results">
{{ result | json}}
</button>
</ion-list>
And then changed the type of results
to Array<any>
. The scanning code now looks like this:
this.ble.startScan([])
.subscribe(device => {
this.results.push(device); //Does not work
});
But the list is not displayed until some other components in the screen change. Apparently Angular does not detect the change inside the Array elements, it only detects changes to references and properties inside objects. So I've tried this inneficient hack:
this.ble.startScan([])
.subscribe(device => {
this.results = this.results.concat([device]); //Does not work
});
But even that didn't work. Then after some hours of reading I knew about this thing called ChangeDetector
which allegedly should do the trick. I tried the OnPush detection strategy and also the default to no avail:
this.ble.startScan([])
.subscribe(device => {
this.results = this.results.concat([device]);
this.changeDetector.markForCheck() //Does not work
});
And of course it doesn't work because it just marks for check, but does not perform the checking at that very moment.
TL;DR ELI5 what on Earth do you need to do in Ionic (or Angular) to add an element to a list?