Can you modify your JSON to have a loaded
boolean property? If you can this will be easy, do as this:
<ion-card *ngFor="let item of items">
<img [src]="item.picture" (load)="item.loaded = true" [hidden]="!item.loaded" />
<img src="../path/to/your/placeholer/image.jpg" [hidden]="item.loaded">
</ion-card>
You'll have an loaded property always initalized as false
, when the image loads the (load)
event will be fired and change the image loaded property to true, hidding the placeholder image and showing the loaded imagem.
If you can't change this JSON (or if it's too big to edit) you can use the above code, but do the following in your page .ts
public functionWhoseIsLoadingYourJson(){
// HTTP REQUEST FOR JSON
.subscribe(response => {
response.forEach(element => {
element.loaded = false;
});
this.items = response;
});
}
Just iterate your response and in every object set a loaded property to false. If this throw some error you can put your <ion-card>
inside a div with a *ngIf
<div *ngIf="this.items != null">
<!-- ion card -->
</div>
EDIT - Updating JSON
Since it's coming from Firebase there's three options to update your JSON. The first one is a function whose you would execute just once to update your database, the second still is the code i gave (iterating through results and pushing the boolean value) but itll be different since you're using Firebase.
First solution:
Somewhere in your code, it can be any page, you just need to execute it once:
firebase.database().ref('myDataNode').on('value', snapshot => {
for(let key in snapshot.val()){
firebase.database().ref('myDataNode/' + key + '/loaded').set(false);
}
});
See that i'm looping through all resuts in your myDataNode
and using their key to set a loaded
property to false
. But take care when using set
since you can override all your nodes, before doing this method remember exporting your Firebase node to have a backup. And if you're pushing your images to Firebase from anywhere in your code remember to change it to set a loaded
property together.
The second one, as mentioned, is what i've done up in this answer, but now using it inside your Firebase call and using the forEach method that comes along with snapshot:
firebase.database().ref('myDataNode').on('value', snapshot => {
snapshot.forEach(element =>{
this.myDataNode.push({
picture: element.val(), // maybe it needs to be element.val().nameOfYourProperty
loaded: false
})
});
});
This'll push a new element to your array with the picture url and the loaded property. If it can't recognize the .push()
method just declare your variable typed as an array:
public myDataNode: any[];
The third one is just updating locally, itarate through your firebase snapshot, save the result in a local variable, create a new property and push it to your array:
firebase.database().ref('myDataNode').on('value', snapshot => {
for (let key in snapshot.val()){
snapshot.forEach(item => { // iterate snapshot
let record = item.val(); // save the snapshot item value in a local variable
record.loaded = true; // add the property
this.newArray.push(record); // push it to your array that'll be used in ng-for
return true; // return true to foreach
});
}
});
Hope this helps.