Here is my code:
var userRef = new Firebase("https://awesome.firebaseio.com/users/");
var tokenRef = userRef.child(key+'/tokens');
tokenRef.once('value', function(snapshot){
var userTokenSync = $firebase(tokenRef);
var userTokens = userTokenSync.$asArray();
console.log(userTokens);
console.log(userTokens[0]);
for(var i=0, len = userTokens.length; i < len; i++) {
console.log(userTokens[i]);
}
console.log('done');
})
This code gets the tokens of a user from firebase, and I just want to browse the tokens array.
Here is what the console gives me:
As you can see, I cannot access the array. Do you have any idea of how I could do this?
Thanks in advance.
Welcome to Asynchronous Loading 101.
var userTokens = userTokenSync.$asArray();
console.log(userTokens);
console.log(userTokens[0]);
for(var i=0, len = userTokens.length; i < len; i++) {
console.log(userTokens[i]);
}
console.log('done');
The first line of this snippets starts loading your data from Firebase. But that loading might take some time. And since the browser doesn't want to block things, it continues executing the script.
By the time the browser executes your console.log(userTokens);
the data most likely hasn't been loaded yet. So it just prints the object to the console as a placeholder.
By the time it gets to the for
loop, the data may or may not yet have been loaded from Firebase.
At some point you clicked the arrow next to the logged userTokens
. By that time the data had loaded from Firebase and the console shows the latest data.
The solution is provided by AngularFire, in the form of a promise. AngularFire promises to at some point in the future have the data for you. If you have a piece of code that should only execute when the data is loaded, you can write it like this:
var userTokens = userTokenSync.$asArray();
console.log(userTokens);
console.log(userTokens[0]);
userTokens.$loaded(function(userTokens) {
for(var i=0, len = userTokens.length; i < len; i++) {
console.log(userTokens[i]);
}
console.log('done');
});
console.log('at last line, but not done yet');
Note that the above is a bad example of when to use $loaded
. Since $loaded
will fire only once, it will only log the initial contents of the array. If you're just trying to see if/when your data has loaded, the idiomatic approach is to add the userTokens
to the scope:
$scope.userTokens = userTokens;
And add this to your view/HTML:
<pre>{{ userTokens | json }}</pre>
AngularFire will now monitor when the userTokens are loaded or modified in any way and will tell AngularJS to update the view if that happens.
Also see these:
Yup... we get this question a lot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With