Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase not receiving data before view loaded - empty array returned before filled

In the following code I save each item's key and an email address in one table, and to retrieve the object to fetch from the original table using said key. I can see that the items are being put into the rawList array when I console.log, but the function is returning this.cartList before it has anything in it, so the view doesn't receive any of the data. How can I make it so that this.cartList waits for rawList to be full before it is returned?

 ionViewWillEnter() {
    var user = firebase.auth().currentUser;
    this.cartData.getCart().on('value', snapshot => {
        let rawList = [];
        snapshot.forEach(snap => {
          if (user.email == snap.val().email) {
            var desiredItem = this.goodsData.findGoodById(snap.val().key);
            desiredItem.once("value")
            .then(function(snapshot2) {
              rawList.push(snapshot2);
            });
            return false
          }
        });
        console.log(rawList);
        this.cartList = rawList;
    });
  }

I have tried putting the this.cartList = rawList in a number of different locations (before return false, even inside the .then statement, but that did not solve the problem.

like image 529
maudulus Avatar asked May 09 '17 19:05

maudulus


1 Answers

The following function call is asynchronous and you're falling out of scope before rawList has a chance to update because this database call takes a reasonably long time:

desiredItem.once("value").then(function(snapshot2) {
    rawList.push(snapshot2);
});

You're also pushing the snapshot directly to this list, when you should be pushing snapshot2.val() to get the raw value.

Here's how I would fix your code:

ionViewWillEnter() {
    var user = firebase.auth().currentUser;
    this.cartData.getCart().on('value', snapshot => {
        // clear the existing `this.cartList`
        this.cartList = [];
        snapshot.forEach(snap => {
          if (user.email == snap.val().email) { 
            var desiredItem = this.goodsData.findGoodById(snap.val().key);
            desiredItem.once("value")
            .then(function(snapshot2) {
              // push directly to the cartList
              this.cartList.push(snapshot2.val());
            });
          }
          return false;
        });
    });
  } 
like image 65
Bradley Mackey Avatar answered Sep 18 '22 00:09

Bradley Mackey