m1l05z
m1l05z

Reputation: 378

Ionic 2 ngFor update data in view

In my project 'Infinite scroll calendar' I use ngFor to interate over object using 'pipe' mapToIterable.

Unfortunately, I notice when I add new properties to object on view variable is updated but ngFor not updating the list. The thing is that when I enter the view it fills fine but when I scroll down it successfully retrieves data from API but not update the list in ngFor..

I tried workaround problem by placing code in zone.run() without success.

#ionic info

Your system information:

Cordova CLI: 6.4.0 
Ionic Framework Version: 2.0.0-rc.3
Ionic CLI Version: 2.1.18
Ionic App Lib Version: 2.1.9
Ionic App Scripts Version: 0.0.45
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 4.4
Node Version: v6.5.0
Xcode version: Not installed

Time for some code:

// mapToIterable.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'mapToIterable'})
export class MapToIterablePipe implements PipeTransform {
  transform(value): any {
    let keys = [];
    for (let key in value) {
      keys.push({ key: key, value: value[key]});
    }
    return keys;
  }
}

.

// index.ts
export class Appointments {
  appointments = {};
  current_date = new Date();
  top_date: any = new Date(+new Date - 12096e5);  // 14 days past
  bottom_date: any = new Date(+new Date + 12096e5);  // 14 day future
  range = {
    start_date: this.top_date,
    end_date: this.bottom_date
  }

  generateDays = function (start, end) {
    while(start < end) {
      start.setDate(start.getDate() + 1);
      this.appointments[start.toISOString().slice(0, 10)] = [];
    }
  };

  fillDays = function () {
    this.appointmentService.all(this.range).map(res => res.json()).subscribe(
      data => {
        for (var appointment in data) {
          this.appointments[appointment] = data[appointment];
        }
      },
      err => {
        console.log(JSON.parse(err._body));
      }
    );
  };

  constructor(
    public navCtrl: Nav,
    public appointmentService: AppointmentService,
  ) {
    var temp_date: any = new Date(this.top_date);
    this.generateDays(temp_date, this.bottom_date);
    this.fillDays();
  }

  moreFuture(infiniteScroll) {
    setTimeout(() => {
      var temp_date: any = new Date(this.bottom_date);
      this.bottom_date = new Date(+temp_date + 12096e5); // add 14 days
      this.range.start_date = temp_date;
      this.range.end_date = this.bottom_date;
      this.generateDays(temp_date, this.bottom_date);
      this.fillDays();
      infiniteScroll.complete();
    }, 500);
  };
}

.

// index.html
 <ion-content padding>
  {{appointments | json}}
  <ion-list class="calendar-list">
    <div *ngFor="let appointment of appointments | mapToIterable" [id]="appointment.key">
      <ion-item class="day past">
        <ion-avatar class="date" item-left>
          <h1>{{appointment.key | date: 'dd'}}</h1>
          <h2>{{appointment.key | date: 'MMM'}}</h2>
        </ion-avatar>
        <div *ngIf="!!appointments[appointment.key].length">
          <ion-avatar class="inline" text-center padding>
            {{appointments[appointment.key][0].patient.first_name[0]}}{{appointments[appointment.key][0].patient.last_name[0]}}
          </ion-avatar>
          <div class="inline">
            <h2 class="username" text-wrap>
              {{appointments[appointment.key][0].patient.first_name}}
              {{appointments[appointment.key][0].patient.last_name}}
            </h2>
            <p>
              <ion-icon name="clock-gray"></ion-icon>
              {{appointments[appointment.key][0].time_start | date: 'HH:mm'}}
              -
              {{appointments[appointment.key][0].time_end | date: 'HH:mm'}}
            </p>
          </div>
        </div>
      </ion-item>
    </div>
    <ion-infinite-scroll (ionInfinite)="moreFuture($event)">
      <ion-infinite-scroll-content></ion-infinite-scroll-content>
    </ion-infinite-scroll>
  </ion-list>
</ion-content>

The reason is that I'm using an object rather than an array?

I will be grateful for every answer :)

Upvotes: 2

Views: 1306

Answers (1)

Suraj Rao
Suraj Rao

Reputation: 29614

This is because you are using a 'pure pipe' which executes when the value or reference it is applied to changes. It does not detect object property changes.In your case, the mapToIterable pipe is not aware of the changes occuring to properties of your object Check here

Try

@Pipe({name: 'mapToIterable',pure:false})

Upvotes: 3

Related Questions