I am starting with IONIC+Javascript+Async functions and having a situation that I'm stuck with.
I have an "index" page that will load data from a service and show it with ngFor. If there is no data, I want to show an ion-row saying No Media Found. Only if there is no data from the service it is going to be shown.
Here is my relevant part of the home.page.ts
constructor(private mediaSvc: MediaService){
this.loading = true;
}
ionViewDidEnter() {
console.log("ionViewDidEnter before getMedia - loading ", this.loading);
this.getMedia();
console.log("ionViewDidEnter after getMedia - loading ", this.loading);
}
getMedia() {
console.log("getMedia inside");
this.mediaSvc.getMedia().then(result => {
this.arr = result || [];
this.loading = false;
console.log("getMedia inside promisse - loading ", this.loading);
});
}
And here is my relevant code inside home.page.html
<ion-grid class="ion-no-padding">
<ion-row>
<ion-col>
<ion-list>
<ion-item *ngFor="let data of arr">
<ion-icon name="film" slot="start"></ion-icon>
<div tappable>
<h2>
<strong>{{data.name}}</strong> / Episode:
{{data.episode}}
</h2>
<h3>
Film Period:
<em>
<strong>{{ data.startDate | date: "MMMM dd, yyyy"}}</strong>
to
<strong>{{ data.endDate | date: "MMMM dd, yyyy"}}</strong>
</em>
</h3>
</div>
<div slot="end">
<ion-button fill="clear" (click)="showOptions(data)">
<ion-icon name="ellipsis-vertical-sharp"></ion-icon>
</ion-button>
</div>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
<ion-row *ngIf="!loading">
<ion-col class="ion-text-center">
<ion-text><h2>No media found!</h2></ion-text>
</ion-col>
</ion-row>
</ion-grid>
Inside the media.service.ts
getMedia() {
return new Promise<any[]>(resolve => {
let arr = [];
let fakeData = {};
fakeData = {
id: 1,
name: "Test 1",
description: "This is a fake test",
startDate: "January 1, 2020",
endDate: "",
episode: 1,
slates: []
};
arr.push(fakeData);
fakeData = {
id: 2,
name: "Test 2",
description: "This is a fake test 2",
startDate: "January 1, 2010",
endDate: "December 31, 2011",
episode: 1,
slates: []
};
arr.push(fakeData);
resolve(arr);
});
}
What happens is, as the mediaSvc.getMedia is async, at the time I test if !loading, it is still true. I need it false (not loading anymore, I set it to false on my getMedia).
The results I'm getting are always showing the "No Media Found" after the data being loaded.
I have this result with my console logs.
ionViewDidEnter before getMedia - loading true
getMedia inside
ionViewDidEnter after getMedia - loading true
getMedia inside promisse - loading false
How do I deal with this? I mean, how can I test these conditions for true/false if it is async? Moreover, is there another approach to this situation?
I'm starting with this stack, so I might be missing something simple.
When you retrieve the data, you then set loading to false. In the html, you have the if statement set so that if loading is false, it displays the 'No media found' message.
So this is correct behaviour for the logic.
You want the message to show if there are no items returned. This could be done with:
<ion-row *ngIf="!arr || arr.length == 0">
<ion-col class="ion-text-center">
<ion-text><h2>No media found!</h2></ion-text>
</ion-col>
</ion-row>
See StackBlitz demo (comment out all arr.push(fakeData); lines in media.service to see 'No items found' message).