Problems with Observable.interval - data is not updated in the template, ngFor - incorrect length, receiving polling data at startup

in my constant struggle to teach myself Angular2 (the next time I have vacation days, I’m going on vacation!), and I have a problem ... I have a service that retrieves user data from fan REST service I created. In my service I want to poll the data (in this case, I am mocking friends who are online and friends who are not connected to the network). Here is a service with a survey code:

@Injectable()
export class UserDataService {

    public loginInUser: Subject<UserStatus> = new BehaviorSubject<UserStatus>(null);
    public currentUser: UserStatus;
    public onlineContacts: Subject<UserContact> = new BehaviorSubject<UserContact>(null);
    public userContacts: Subject<UserContact> = new BehaviorSubject<UserContact>(null);

    constructor(public http:Http) {
        this.loadUserStatus(); // this is lower in the Component... I have not included it here
        this.pollContacts();
    }

    private pollContacts() : any {

        var headers = new Headers();
        headers.append('Content-Type', 'application/json');

        return Observable.interval(30000)
            .switchMap(() => this.http.get('/restservice/contacts', {headers: headers}))
            //.startWith() - Would this allow me to kick off the service when the Component is loaded / called?
            .subscribe((data: any) => {
                data = data.json();
                this.onlineContacts.next(data.onlineContacts);
                this.userContacts.next(data.allContacts);
            });

    }

Here is my component that calls the service:

@Component({
    selector: 'contacts-list',
    directives: [...ROUTER_DIRECTIVES],
    template: require('./contact-list.html')
})

export class ContactsList {

    public onlineContacts: any;
    public userContacts: any;

    constructor (public userDataService: UserDataService) {
        this.userDataService.onlineContacts.subscribe(
            (onlineContacts) => {
                this.onlineContacts = onlineContacts;
            });

        this.userDataService.userContacts.subscribe(
            (userContacts) => {
                this.userContacts = userContacts;
            });
    }
}

And here is the HTML view / template for my component ...

<h3>Online Contacts</h3>
<div class="online-contact" *ngIf="onlineContacts?.length > 0" *ngFor="#con of onlineContacts" [routerLink]="['ForeignProfile', {id: con.persId}]">
    <img [src]="con.imgUrl" class="img-circle online-contact-img">
    {{ con.name }}
</div>

<h3>Contacts</h3>
<div class="online-contact" *ngIf="userContacts?.length > 0" *ngFor="#con of userContacts" [routerLink]="['ForeignProfile', {id: con.persId}]">
    <img [src]="con.imgUrl" class="img-circle offline-contact-img">
    {{ con.name }}
</div>

Now I am facing problems ...

  • -, pollContacts(), /, . .startWith (. ), , ?

  • ... ? async ( , )?

  • - ngFor ( ) , . , *ngFor="#con of onlineContacts" ( ), , *ngFor="#con of userContacts" 20 ( 20 ), userContacts - 19!

, , , , , . .

+4
2

, , startWith, switchMap one:

return Observable.interval(3000)
        .startWith('')
        .switchMap(() => this.http.get('./app/restservice/contacts', {headers: headers}))
        .subscribe((data: any) => {
        });

async, . subscribe, .

@Component({
  template: `
    <h3>Contacts</h3>
    <div class="online-contact" *ngFor="#con of userContacts | async">
      <img [src]="con.imgUrl" class="img-circle offline-contact-img">
      {{ con.name }}
    </div>
  `
})
export class ContactsList {
  public onlineContacts: any;
  public userContacts: any;

  constructor (public userDataService: UserDataService) {
    this.userContacts = this.userDataService.userContacts;
  }
}

, BehaviorSubject s. , . - :

{
  "allContacts": [
    {
      "name": "Sparky",
      "imgUrl": "https://restlet.com/static/app/img/sparky_right.png"
    }
  ],
  "onlineContacts": [
    {
      "name": "Sparky",
      "imgUrl": "https://restlet.com/static/app/img/sparky_right.png"
    }
  ]
}

plunkr: https://plnkr.co/edit/vYQPePG4KDoktPoGaxYu?p=preview.

+1

, Angular :

@Component({
    selector: 'contacts-list',
    directives: [...ROUTER_DIRECTIVES],
    template: require('./contact-list.html'),
    changeDetection: ChangeDetectionStrategy.OnPush // <== added (optional)
})

export class ContactsList {

    public onlineContacts: any;
    public userContacts: any;

    constructor (public userDataService: UserDataService,
        private cd: ChangeDetectorRef // <== added
    ) {
        this.userDataService.onlineContacts.subscribe(
            (onlineContacts) => {
                this.onlineContacts = onlineContacts;
                this.cd.markForCheck(); // <== added
            });

        this.userDataService.userContacts.subscribe(
            (userContacts) => {
                this.userContacts = userContacts;
                this.cd.markForCheck(); // <== added
            });
    }
}

. http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

+1

All Articles