Reputation: 1210
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
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