View is rendering before storage promise is resolved so data is not being displayed


#1

I am retrieving data from storage. I can retrieve it just fine, however the view renders before the promise is resolved so it doesn’t display any data. I know that the data is retrieved because I am logging it.

storage provider

getData(): any {
	let data = [];
	return this.storage.forEach((value, key, index) => {
	  if (key.startsWith("KEY-")) {
	    data.push(value);
	  }
	}).then(() => data);
}

component.ts

let test = this.storage.getSessionData().then((data) => {
  this.dataArr = data;
  // Shows data
  console.log("data", this.dataArr);
});

// Shows empty
console.log("data", this.dataArr);

html

<ion-list>
  <ion-list-header> Data </ion-list-header>
  <ng-container *ngIf="data && data.id; else noData">
    <ion-item *ngFor="let d of data" text-wrap>
    	{{d.id}}
     </ion-item>
</ion-list>

<ng-template #noData>
    <ion-list>
      <ion-list-header> Data </ion-list-header>
      <ion-item>No Data</ion-item>
    </ion-list>
</ng-template>

#2

If you want to be able to distinguish in your template between “looked in storage, found nothing” (case a) and “not yet done looking in storage” (case b), you are going to have to manage that yourself. One way is with a separate boolean flag that is raised when getSessionData() resolves. Another way would be to deliberately fail to initialize the data array in the page component (this is one of the rare situations where I recommend doing this). That way !data is case b and data && data.length === 0 is case a.


#3
<ng-container *ngIf="data && data.id; else noData">

The data variable is only available in the resolve function of your promise. You should check for dataArr in your template:

<ng-container *ngIf="dataArr && dataArr.id; else noData">
<ion-item *ngFor="let d of dataArr" text-wrap>

And you are sure your dataArr has an id property and is an array, too?