简体   繁体   中英

Angular: RxJS Observable only updating on timeout

I have an injectable service which performs BLE scans and streams the results through an observable to the page component where it is then stored in a local variable and displayed (in theory).

The issue is that updates coming from the startScanWithOptions method do not cause the view to be updated, while updates from the setInterval method do cause an update of the view. The update is making it to the page component as all updates are being written to the console, but not showing up until the setInterval updates cause a render.

From the injectable service:

start() {
    this.connections$ = new Observable((observer) => {
        if (this.blePlugin) {
            this.blePlugin.startScanWithOptions(
                [],
                { reportDuplicates: true },
                (result) => this.observableScanResult(result, observer)
            );
        }
        setInterval(()=>{this.observableScanResult({rssi: 100}, observer)}, 1000);
    });
    return this.connections$;
}

private observableScanResult(result, observer) {
    observer.next(result);
}

From the page component:

private startSelection() {
    console.log('Scan Starting');
    this.connectionSource = this.connection.start();
    this.connectionSub = this.connectionSource.subscribe((result) => {
      this.test.push(result.rssi);
      console.log(this.test);
    });
}

Updates coming from the startScanWithOptions() method are likely running outside the Angular zone, meaning that the asynchronous event is not monkey-patched by Zone.js, like setTimeout() is.

In startSelection() , manually trigger change detection inside your subscribe() callback:

export class MyComponent {
  constructor(private _cdRef:ChangeDetectorRef) {}
  private startSelection() {
    console.log('Scan Starting');
    this.connectionSource = this.connection.start();
    this.connectionSub = this.connectionSource.subscribe((result) => {
      this.test.push(result.rssi);
      console.log(this.test);
      this._cdRef.detectChanges();   // <---------
    });
}

See also Triggering Angular2 change detection manually .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM