Acesso asynchronous a um array no Firebase

Aqui está o meu 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'); }) 

Esse código obtém os tokens de um usuário do Firebase e eu só quero procurar o array de tokens.

Aqui está o que o console me oferece:

insira a descrição da imagem aqui

Como você pode ver, não consigo acessar o array. Você tem alguma ideia de como eu poderia fazer isso?

Desde já, obrigado.

Bem-vindo ao carregamento asynchronous 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'); 

A primeira linha desses snippets começa a carregar seus dados do Firebase. Mas esse carregamento pode levar algum tempo. E como o navegador não quer bloquear as coisas, continua executando o script.

No momento em que o navegador executa seu console.log(userTokens); os dados provavelmente ainda não foram carregados. Por isso, apenas imprime o object para o console como um espaço reservado.

No momento em que chega ao loop for , os dados podem ou não ter sido carregados do Firebase.

Em algum momento você clicou na seta ao lado do userTokens registradoTokens. Nesse momento, os dados foram carregados do Firebase e o console mostra os dados mais recentes.

A solução é fornecida pelo AngularFire, na forma de uma promise. AngularFire promete em algum momento no futuro ter os dados para você. Se você tem um pedaço de código que só deve ser executado quando os dados são carregados, você pode escrevê-lo assim:

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

Atualizar

Note que o acima é um mau exemplo de quando usar $loaded . Como $loaded será acionado apenas uma vez, ele registrará apenas o conteúdo inicial da matriz. Se você está apenas tentando ver se / quando seus dados foram carregados, a abordagem idiomática é adicionar o userTokens ao escopo:

 $scope.userTokens = userTokens; 

E adicione isso à sua visualização / HTML:

 
{{ userTokens | json }}

O AngularFire agora irá monitorar quando o usuárioTokens for carregado ou modificado de qualquer forma e irá dizer ao AngularJS para atualizar a visualização se isso acontecer.

Veja também estes:

  • Firebase, AngularJS e GeoFire - aguarde a resposta da fábrica
  • Firebase angularfire child. $ AsObject fornece propriedades indefinidas
  • angularfire - por que não posso fazer o loop da matriz retornada pelo $ asArray?
  • Passando variável no escopo pai para a function de retorno de chamada
  • Tentando obter registros de filhos do Firebase

Sim ... nós recebemos essa pergunta muito.