Acceso asincrónico a una matriz en Firebase

Aquí está mi código:

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'); }) 

Este código obtiene los tokens de un usuario de firebase, y solo quiero navegar en el conjunto de tokens.

Esto es lo que la consola me da:

enter image description here

Como puede ver, no puedo acceder a la matriz. ¿Tienes alguna idea de cómo podría hacer esto?

Gracias por adelantado.

Bienvenido a 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'); 

La primera línea de estos fragmentos comienza a cargar tus datos desde Firebase. Pero esa carga puede llevar algo de tiempo. Y dado que el navegador no quiere bloquear cosas, continúa ejecutando el script.

Para cuando el navegador ejecute su console.log(userTokens); los datos probablemente no se hayan cargado aún. Por lo tanto, solo imprime el objeto en la consola como marcador de posición.

Cuando llega al bucle for , los datos pueden haber sido cargados o no desde Firebase.

En algún momento, hizo clic en la flecha al lado de los userTokens registrados. Para ese momento, los datos se habían cargado desde Firebase y la consola muestra los datos más recientes.

AngularFire proporciona la solución en forma de promesa. AngularFire promete en algún momento en el futuro tener los datos para usted. Si tiene un fragmento de código que solo debe ejecutarse cuando se cargan los datos, puede escribirlo así:

  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'); 

Actualizar

Tenga en cuenta que lo anterior es un mal ejemplo de cuándo usar $loaded . Como $loaded activará solo una vez, solo registrará los contenidos iniciales de la matriz. Si solo está tratando de ver si sus datos se cargaron, el enfoque idiomático es agregar los userTokens al scope:

 $scope.userTokens = userTokens; 

Y agregue esto a su vista / HTML:

 
{{ userTokens | json }}

AngularFire ahora controlará cuando los UserTokens se carguen o modifiquen de cualquier manera y le dirá a AngularJS que actualice la vista si eso sucede.

Ver también estos:

  • Firebase, AngularJS y GeoFire: espere la respuesta de fábrica
  • Firebase angularfire child. $ AsObject da propiedades indefinidas
  • angularfire: ¿por qué no puedo recorrer la matriz devuelta por $ asArray?
  • Pasar la variable en el scope principal a la función de callback
  • Intentando obtener registros secundarios de Firebase

Sí ... tenemos esta pregunta mucho.