Reputation: 378
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
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