Reputation: 349
My template:
<ion-item-sliding *ngFor="let draft of drafts">
<ion-item>
<h2>Report draft header</h2>
</ion-item>
<ion-item-options side="left">
<button ion-button color="secondary" (click)="draftUpload(draft.report.pk)">
<ion-icon name="md-cloud-upload"></ion-icon>
Upload
</button>
</ion-item-options>
</ion-item-sliding>
In the controller, I do this:
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.drafts = this.dataService.getDraftReports();
}
Here is the getDraftReports() functions:
getDraftReports() {
var draftReports = [];
let reportObj : any;
this.storage.forEach((value, key, index) => {
reportObj = JSON.parse(value);
if(reportObj.report.uploaded=="no"){
draftReports.push(reportObj);
}
});
return draftReports;
}
This doesn't work, although the DB changes are made. If I refresh the page, or navigate away and back, the list updates.
What am I doing wrong?
Upvotes: 1
Views: 3010
Reputation: 29625
this.storage.foreach
returns a promise and hence is asynchronous.
Your draftReports
array is returned before it is set.You need to return the promise :
getDraftReports(draftsHandler:any) {
//var draftReports = [];
//Use a filter method and return the promise.
return this.storage.forEach((value, key, index) => {
let reportObj : any;
reportObj = JSON.parse(value);
if(reportObj.report.uploaded=="no"){
//draftReports.push(reportObj);
draftsHandler(reportObj);
}
});
}
In your draftUpload
set drafts
within then
.
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.dataService.getDraftReports((data)=>this.draftsHandler(data)).then(()=>{
//next steps
}
}
draftsHandler(data:any){
this.drafts.push(data)
}
Upvotes: 1
Reputation: 2638
It seems a change detection issue. Change detection is fired on every browser event, timeout or http request.
The case is that your function: getDraftReports() is asyncronous and is its callback is not detected for Angular and consequently it doesn't fires the change detection event in order to update the view.
In order to solve this you will have to wrap this function into the angular zone. See this code:
import zone:
import { NgZone } from '@angular/core';
Inject the service ngZone:
constructor(private zone: NgZone) {
....
}
And finally add this to your function:
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.zone.run(
() => {
this.drafts = this.dataService.getDraftReports();
}
)
}
Hope this helps.
Upvotes: 2