Muhammad
Muhammad

Reputation: 349

Ionic 2 - List update doesn't reflect in UI unless page is refreshed

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

Answers (2)

Suraj Rao
Suraj Rao

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

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

Related Questions