Pregunta

I want to know how to loop through the children of everyone. I'm using Firebase and AngularJS.

My firebase object looks like:

Firebase Objects

To me it looks like a dictionary, so from Getting a list of associative array keys I have tried

syncData('everyone').$bind($scope, 'everyone').then(function() {
  var keys = $scope.everyone.$getIndex();
  for (var key in $scope.everyone) {
   console.log("key : " + key + " value : " + $scope.everyone[key]);
  }
});

The log does contain the child objects, but it also includes all the methods. Like so

... Before this line is all the other methods.
key : $on value : function (a,c){if("loaded"==a&&b._loaded)return b._timeout(function(){c()}),void 0;if(!b._on.hasOwnProperty(a))throw new Error("Invalid event type "+a+" specified");b._on[a].push(c)} controllers.js:58
key : $off value : function (a,c){if(b._on.hasOwnProperty(a))if(c){var d=b._on[a].indexOf(c);-1!==d&&b._on[a].splice(d,1)}else b._on[a]=[];else b._fRef.off()} controllers.js:58
key : $auth value : function (a){var c=b._q.defer();return b._fRef.auth(a,function(a,b){null!==a?c.reject(a):c.resolve(b)},function(a){c.reject(a)}),c.promise} controllers.js:58
key : $getIndex value : function (){return angular.copy(b._index)} controllers.js:58
key : -JH45WOOAtnZfUZkrJb1 value : [object Object] controllers.js:58
key : -JH45YdfwptGv3y6UqyV value : [object Object] controllers.js:58
key : -JH45_zxptV_dmibyGzL value : [object Object] 

Is there a way I can get just the children?

I'm doing this because my code was designed to use an array, but Firebase discourage using arrays (for values that multiple people could change). So I'm trying to loop through the firebase dictionary and copy the objects into an array on the client side. So I don't have to change too much of my code.

¿Fue útil?

Solución

UPDATE: As of AngularFire 0.8.x, one can use $asArray() to obtain a sorted array of the records and this answer is no longer necessary

The correct way to iterate values in an angularFire object is by using $getIndex(). You have this in your code above, but did not utilize it in the for loop.

Since you are already using the angularFire lib (syncData is the angularFire-seed service that uses angularFire), there is no need to worry about calling $apply() or any of the other complexities of coaxing data into Angular detailed in the previous answer (which is a good response for a raw Firebase/Angular implementation).

Instead, just change your for loop to iterate the keys instead of the angularFire instance:

syncData('everyone').$bind($scope, 'everyone').then(function() {
  var keys = $scope.everyone.$getIndex();

  // utilizing Angular's helpers
  angular.forEach(keys, function(key) {
     console.log(key, $scope.everyone[key]);
  });

  // or as a for loop
  for(var i=0, len = keys.length; i < len; i++) {
     console.log(keys[i], $scope.everyone[keys[i]]);
  }
});

To utilize the object in the DOM, use ng-repeat:

<ul>
  <li ng-repeat="(key,user) in everyone">{{key}}, {{user|json}}</li>
</ul>

Otros consejos

The way I do it is pretty simple, you just push all the children into an array when they arrive like this.

Everyone.on('child_added', function(snap) {
  implementLogic(snap.val());
  $scope.$apply();
});

function implementLogic(person) {
  $scope.everyone.push(person);

  if (something) {
    $scope.todaysPeople.push(person);
  }
  if (something else) {
    $scope.peopleToTest.push(person);
  }
  ...
}

That leaves you with an array of the child objects you want.

Use ng-fire-alarm with collection: true like this:

angular.module('demo', ['ng-fire-alarm']).controller('IndexCtrl', IndexCtrl);

function IndexCtrl ($scope) {
  var everyone = new Firebase(URL).child('everyone');
  everyone
  .$toAlarm({collection: true}) // will transform object into native array
  .$thenNotify(function(everyones){ // notify you on ANY changes 
    $scope.everyones = everyones;
  });
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top