Jonathan Brizio
Jonathan Brizio

Reputation: 1210

Why are binding to my view only the first element using AngularFire?

I having troubles to show in my view the content storage on Firebase DB. I know that Firebase is asynchronous. This is my current structure on my Firebase Database:


Code:

    var bigObject = {};

    // Find all recognitions
    var ref = firebase.database().ref('recognitions');

    ref.once('value').then(function(snapshot) {
        bigObject = snapshot.val();
        // Loop through all recognitions
        for (o in bigObject) {
            var ref2 = firebase.database().ref('employees').child(bigObject[o].employee);
            ref2.once('value').then(function(snapshot2) {
                bigObject[o].profile = snapshot2.val();
                // Bind the content to the view
                $scope.$apply(function() {
                  $scope.data = bigObject;
                });
            });
        }
    });

My concern is why are binding to my scope only the first element of bigObject? I guess that is an asynchronous error. How can solve that?.

Upvotes: 1

Views: 62

Answers (1)

Schlaus
Schlaus

Reputation: 19212

You are running into the infamous loop issue.

The problem is that when your callback executes, the value of o is no longer what you're expecting it to be.

Here's a simplified example, where the first version demonstrates what's essentially happening with your code, and the second version shows one way to solve the issue:

/**
 * This wont work properly
 */
var obj = {
  a: 'Original',
  b: 'Original',
  c: 'Original'
}

for (var i in obj) {
  var fn = function() {
    obj[i] = 'Updated'
  }
  setTimeout(fn, 4)
}

setTimeout(function() {
  console.log('Object 1', obj)
}, 20)


/**
 * ...but this will
 */
 
var obj2 = {
  a: 'Original',
  b: 'Original',
  c: 'Original'
}

for (var i in obj2) {
  var fn = function(i) {
    obj2[i] = 'Updated'
  }.bind(this, i);
  setTimeout(fn, 4)
}

setTimeout(function() {
  console.log('Object 2', obj2)
}, 60)

There are of course many ways to go about this, but a simple solution would be to bind the proper index to your callback.

Upvotes: 2

Related Questions