web-dev-qa-db-fra.com

angular.forEach et objets

Le problème:

Je fais (ce que je pense est mais peut-être pas) un simple angular.forEach sur un tableau puis en utilisant $resource pour effectuer un appel en fonction de chaque valeur renvoyée. Le résultat de chaque appel est un objet, comme je l'attends. Mais, je ne peux pas obtenir que ces objets se rejoignent harmonieusement comme le montre la documentation angular.forEach .

Mais d'abord, du code qui fonctionne, puis un aperçu du code qui échoue.

Fonctionne :

var uniqueIds = {};
angular.forEach(object, function(key, value){
    this.Push(key.uniqueIds);
}, uniqueIds);
console.log(uniqueIds)
// uniqueIds equals the expected array

Échoue

Voici où les choses se compliquent. Maintenant, dans l'exemple suivant, à l'intérieur du angular.forEach est un $resource appel.

angular.forEach(array, function(index){
    Resource.query({id:index}, function(result){
        console.log(result)
        // returns the expected object, 
        // but, as expected, I can't access the object outside the async call
    });
    console.log(result);
    // result is undefined
 });

Étant donné l'async-ness, il semble qu'une promesse pourrait résoudre le problème. Mais ce n'est pas le cas - je suis vraiment toujours à l'intérieur de l'appel asynchrone. L'affectation de result à $scope travail. En bref, je n'arrive pas à obtenir une valeur en dehors du Resource.query.

Que dois-je faire?

J'ai besoin de l'objet retourné de chaque $resource appeler pour ajouter jusqu'à un objet (en utilisant angular.extend? J'ai essayé cela) de la même manière que angular.forEach a créé un tableau. J'ai essayé de nombreuses approches différentes, la plupart toutes basées sur les réponses aux questions asynchrones générales posées ici, mais jusqu'à présent en vain. Je suis certain que c'est un problème pour obtenir la valeur de la $resource appeler, mais comment faire dans ce cas, je suis un peu perplexe.

13
jody tate

Quelque chose comme ça?

var promises = [];

angular.forEach(array, function(index) {
  promises.Push(Resource.query(...));
});

$q.all(promises).then(function(result1, result2, result3 ...) {
  // do stuff with result1, result2 ... or
  // var results = Array.prototype.slice.call(arguments);
});
17

Angulaire documentation a un très bon exemple pour cela

var values = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
    this.Push(key + ': ' + value);
 }, log);
4
Yasser

.query renvoie une référence de tableau qui est remplie de données lorsque la xhr est terminée. Étant donné que id est probablement un identifiant unique, la requête renverra un tableau avec un seul élément, c'est pourquoi je vous suggère d'utiliser .get au lieu.

Quoi qu'il en soit, si vous avez toujours l'intention d'utiliser .query vous pouvez faire quelque chose comme:

var arrays = [];
angular.forEach(array, function(index){
    arrays.Push(Resource.query({id:index}, function(result){
        console.log(result)
        // returns the expected object, 
        // but, as expected, I can't access the object outside the async call
    }));
    console.log(result);
    // result is undefined
});

$scope.$watch(function () {
    return arrays;
}, function (arrays) {
    angular.forEach(arrays, function (array) {
       angular.forEach(array[0], function () {
          //Do something with the object fields
       });
    });
});

Comme vous pouvez le voir, le code semble assez mauvais ...

Afin d'obtenir de meilleurs résultats, vous pouvez utiliser:

var objects = [];
angular.forEach(array, function(index){
    objects.Push(Resource.get({ id:index });
});

$scope.$watch(function () {
    return objects;
}, function (objects) {
    angular.forEach(objects, function (obj) {
       angular.forEach(obj, function () {
          //Do something with the object fields
       });
    });
});

Encore mieux si vous laissez AngularJS faire le $watch en affectant objects à un $scope propriété.

2
Minko Gechev