0

I have to go through an array of items and fetch the prices in the realtime database, but I want to show a loading message on start and after I finish loading I want to remove the loading message, but the way I did the message does not work its removed before the end of loading:

let loading = this.loadingCtrl.create({
  content: 'Waiting...'
});
loading.present();

for (let i = 0; i <= this.Cart.length - 1; i++) {
  let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
  product.valueChanges().subscribe((prodData: any) => {
      if (prodData != null) {
          this.Cart[i].item.price = prodData.price[0]; 
      }
  });
}
loading.dismiss();

How can I do this correctly?

3
  • just curious, why are you not using Firestore? ...isn't using JavaScript's Promise.all to fetch those prices in parallel best practise, i.e., push each db read into an array then Promise.all that array. When the promise resolves, hide the indeterminate loader. Commented Jan 10, 2019 at 4:22
  • Hi, Ron, I am new with Firebase and I'm not quite sure how to do it, you can show an example of how to do it using Promise.all? Thanks. Commented Jan 10, 2019 at 22:23
  • it's actually no that hard: something like var myArray = [] then for each read do myArray.push(firebase.firestore().collection("prices").doc(itemId).get()). Then after that iteration, after you fill the array, do Promise.all(myArray).then. The return values will be sitting at the index. (remember if a single read fails, the whole Promise.all fails) Commented Jan 10, 2019 at 22:36

1 Answer 1

1

You need to hide the loading indicator inside the subscriber. The simplest way is to hide it when the first data comes in:

for (let i = 0; i <= this.Cart.length - 1; i++) {
  let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
  product.valueChanges().subscribe((prodData: any) => {
      if (prodData != null) {
          this.Cart[i].item.price = prodData.price[0]; 
      }
      loading.dismiss();
  });
}

A bit more tricky is to hide it after all data comes back, but it doesn't have to be too hard. A simple way is to count how many responses you've gotten back. Once that is the same as the number of items in the cart, you can hide the loading indicator.

var responseCount = 0;
for (let i = 0; i <= this.Cart.length - 1; i++) {
  let product = this.db.object('/menuItems/' + this.Cart[i].item.itemId);
  product.valueChanges().subscribe((prodData: any) => {
      if (prodData != null) {
          this.Cart[i].item.price = prodData.price[0]; 
      }
      if (responseCount++ == this.Cart.length) loading.dismiss();
  });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Forgive me, I tried but I do not have enough reputation to vote.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.