Accesso asincrono a un array in Firebase

Ecco il mio codice:

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

Questo codice ottiene i token di un utente da Firebase e voglio solo sfogliare l’array di token.

Ecco cosa mi dà la console:

inserisci la descrizione dell'immagine qui

Come puoi vedere, non posso accedere alla matrice. Hai idea di come potrei fare questo?

Grazie in anticipo.

Benvenuto in Caricamento asincrono 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 prima riga di questo frammento inizia a caricare i tuoi dati da Firebase. Ma quel caricamento potrebbe richiedere del tempo. E poiché il browser non vuole bloccare le cose, continua a eseguire lo script.

Nel momento in cui il browser esegue il tuo console.log(userTokens); i dati probabilmente non sono ancora stati caricati. Quindi stampa l'object sulla console come segnaposto.

Nel momento in cui arriva al ciclo for , i dati potrebbero ancora non essere stati caricati da Firebase.

A un certo punto, hai fatto clic sulla freccia accanto agli utenti registrati. A quel punto i dati erano stati caricati da Firebase e la console mostra i dati più recenti.

La soluzione è fornita da AngularFire, sotto forma di una promise. AngularFire promette che a un certo punto in futuro avranno i dati per te. Se hai un pezzo di codice che dovrebbe essere eseguito solo quando i dati sono caricati, puoi scriverlo in questo modo:

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

Aggiornare

Si noti che quanto sopra è un cattivo esempio di quando usare $loaded . Poiché $loaded si triggers solo una volta, registra solo il contenuto iniziale dell'array. Se stai solo cercando di vedere se / quando i tuoi dati sono stati caricati, l'approccio idiomatico è quello di aggiungere i userTokens all'ambito:

 $scope.userTokens = userTokens; 

E aggiungi questo alla tua vista / HTML:

 
{{ userTokens | json }}

AngularFire monitorerà ora quando gli userToken vengono caricati o modificati in qualsiasi modo e comunicherà ad AngularJS di aggiornare la vista se ciò accade.

Vedi anche questi:

  • Firebase, AngularJS e GeoFire: attendi la risposta dalla fabbrica
  • Firebase angularfire child. $ AsObject fornisce proprietà indefinite
  • angularfire: perché non posso eseguire il loop su array restituito da $ asArray?
  • Passare la variabile nell'ambito genitore alla funzione di callback
  • Cercando di ottenere record figlio da Firebase

Sì ... abbiamo questa domanda molto.