2

I have a component that stores an array of servers for display in a list. The component subscribes to an observable from a service.

This is the component code:

import {Client} from '../../connectionService/client.service';


@Component({
    templateUrl: 'build/pages/page1/page1.html',
    providers: [Client]
})
export class Page1 {
    servers : any;

    constructor(private client: Client) {
      this.servers = [];
      this.client._myServers.subscribe((newServer: any) => {
        console.log("new server!", newServer);
        this.servers.push(newServer);
      });
}

The view:

  <ul>
    <li *ngFor='#item of (servers)'>
     Name : {{item.name}}
  </li>
</ul>

The service:

import { Injectable } from '@angular/core';
import {Observable}     from 'rxjs/Observable';
import {Subject}  from 'rxjs/Subject';


    @Injectable()
    export class Client {
      private serversSubject: Subject<any>;
      _myServers : Observable<ServerHandler>;

    constructor() {
        this.serversSubject = new Subject<any>();
        this._myServers = this.serversSubject.asObservable();
    }

...

When I found a server(in the same service as above:

      this.serversSubject.next({"name": result.name, "adress": result.address});

"new server!" gets printed, and the servers is updated in the component, but the view don't show the new items. When I go in and out of the page the new servers appear.

Thanks in advance, Markus

  • 1
    See http://stackoverflow.com/questions/37722921/array-of-objects-piped-into-my-custom-filter-always-shows-as-length-of-zero – Günter Zöchbauer Jun 09 '16 at 12:31
  • 1
    Thanks! I'm really surprised that there is no better way to solved this. Using ngfor on a array and dynamically adding elements seems like a very common use case. – Markus A Noren Jun 09 '16 at 12:42
  • If you bind to items of the array, then Angular checks the binding and recognizes the change. Angular2 change detection is extremely fast. This doesn't come for free. – Günter Zöchbauer Jun 09 '16 at 12:45
  • According to https://angular.io/docs/ts/latest/api/common/NgFor-directive.html an addition should cause change propagation. I created a new array on each insertion and still don't see any updates until I cause the view to update in some other way. – Markus A Noren Jun 09 '16 at 12:50
  • Hard to tell. Can you create a Plunker that allows to reproduce? – Günter Zöchbauer Jun 09 '16 at 12:52
  • Hard to reproduce right now as it is dependent on a bluetooth-library and when I try to mock to result with window.setTimeout() the list does get updated. Probably window.setTimeout() triggers the change propagation. I will get back to you if I manage to put a plunker up. – Markus A Noren Jun 09 '16 at 13:06

1 Answers1

0

That's a common problem. Your bluetooth library probably runs outside Angulars zone and when code, that runs outside Angulars zone, updates the model, Angulars change detection is not invoked.

There are different strategies to invoke change detection manually. Triggering Angular2 change detection manually

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567