boucle foreach dans angularjs

110

Je traversais l' forEach loopen AngularJS. Il y a quelques points que je n'ai pas compris à ce sujet.

  1. A quoi sert la fonction itérateur? Y a-t-il moyen de s'en passer?
  2. Quelle est la signification de la clé et de la valeur comme indiqué ci-dessous?

angular.forEach($scope.data, function(value, key){});

PS: J'ai essayé d'exécuter cette fonction sans les arguments et cela n'a pas fonctionné.

Voici mon json:

[
   {
     "Name": "Thomas",
     "Password": "thomasTheKing"
   },
   {
     "Name": "Linda",
     "Password": "lindatheQueen"
   }
]

Mon JavaScriptdossier:

var app = angular.module('testModule', []);

app.controller('testController', function($scope, $http){
   $http.get('Data/info.json').then(
      function(data){
         $scope.data = data;
      }
   );

   angular.forEach($scope.data, function(value, key){
      if(value.Password == "thomasTheKing")
         console.log("username is thomas");
   });
});

Une autre question : pourquoi la fonction ci-dessus n'entre pas sur if condition et imprime "username is thomas" dans la console?

Pragam Shrivastava
la source
6
Parce que vous n'attendez pas que le successvôtre se produise $http.get(), le moment où angular.forEach()cela se produit $scope.datan'est donc toujours pas défini.
Tom
1
Existe-t-il un moyen spécifique de suspendre l'exécution du code jusqu'à ce que le json soit chargé
Pragam Shrivastava
Changez la ligne en ce angular.forEach (values, function (value, key) {console.log (key + ':' + value.Name);});
Israel Ocbina

Réponses:

208

Questions 1 et 2

Donc, fondamentalement, le premier paramètre est l'objet sur lequel itérer. Cela peut être un tableau ou un objet. S'il s'agit d'un objet comme celui-ci:

var values = {name: 'misko', gender: 'male'};

Angular prendra chaque valeur une par une, la première étant le nom, la seconde le sexe.

Si votre objet sur lequel itérer est un tableau (également possible), comme ceci:

[{ "Name" : "Thomas", "Password" : "thomasTheKing" },
 { "Name" : "Linda", "Password" : "lindatheQueen" }]

Angular.forEach prendra un par un en commençant par le premier objet, puis le deuxième objet.

Pour chacun de ces objets, il va donc les prendre un par un et exécuter un code spécifique pour chaque valeur. Ce code est appelé la fonction itérateur . forEach est intelligent et se comporte différemment si vous utilisez un tableau d'une collection. Voici quelques exemples:

var obj = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(obj, function(value, key) {
  console.log(key + ': ' + value);
});
// it will log two iteration like this
// name: misko
// gender: male

La clé est donc la valeur de chaîne de votre clé et la valeur est ... la valeur. Vous pouvez utiliser la clé pour accéder à votre valeur comme ceci:obj['name'] = 'John'

Si cette fois vous affichez un tableau, comme ceci:

var values = [{ "Name" : "Thomas", "Password" : "thomasTheKing" },
           { "Name" : "Linda", "Password" : "lindatheQueen" }];
angular.forEach(values, function(value, key){
     console.log(key + ': ' + value);
});
// it will log two iteration like this
// 0: [object Object]
// 1: [object Object]

Alors la valeur est votre objet (collection) et la clé est l'index de votre tableau puisque:

[{ "Name" : "Thomas", "Password" : "thomasTheKing" },
 { "Name" : "Linda", "Password" : "lindatheQueen" }]
// is equal to
{0: { "Name" : "Thomas", "Password" : "thomasTheKing" },
 1: { "Name" : "Linda", "Password" : "lindatheQueen" }}

J'espère que cela répondra à votre question. Voici un JSFiddle pour exécuter du code et tester si vous le souhaitez: http://jsfiddle.net/ygahqdge/

Déboguer votre code

Le problème semble venir du fait qu'il $http.get()s'agit d'une requête asynchrone.

Vous envoyez une requête sur votre fils, PUIS lorsque votre navigateur termine le téléchargement, il exécute le succès. MAIS juste après avoir envoyé votre demande, vous effectuez une boucle en utilisant angular.forEachsans attendre la réponse de votre JSON.

Vous devez inclure la boucle dans la fonction de réussite

var app = angular.module('testModule', [])
    .controller('testController', ['$scope', '$http', function($scope, $http){
    $http.get('Data/info.json').then(function(data){
         $scope.data = data;

         angular.forEach($scope.data, function(value, key){
         if(value.Password == "thomasTheKing")
           console.log("username is thomas");
         });
    });

});

Cela devrait fonctionner.

Aller plus profondément

L' API $ http est basée sur les API différées / promises exposées par le service $ q. Alors que pour les modèles d'utilisation simples, cela n'a pas beaucoup d'importance, pour une utilisation avancée, il est important de vous familiariser avec ces API et les garanties qu'elles offrent.

Vous pouvez jeter un œil aux API différées / promises , c'est un concept important d'Angular pour faire des actions asynchrones fluides.

Sébastienbarbier
la source
2
Colin B (profil Here .) Voulait commenter cela successet error est obsolète . Il est suggéré d' utiliser la thenméthode au lieu de success. Maintenant, @Colin, sortez et répondez à quelques questions pour obtenir 50 répétitions! : P
Match
3
Async n'est pas parallèle. En parallèle, il aura besoin de webworkers, pas de promesses. Petit peu pédant, mais cela vaut la peine d'arrêter la désinformation à ce sujet chaque fois que cela se produit.
Kyle Baker
1
Merci @KyleBaker, j'ai mis à jour cette réponse, tu as raison "parallèle" était un abus de langage.
sebastienbarbier
@sebastienbarbier pouvez-vous s'il vous plaît m'aider à résoudre ce stackoverflow.com/questions/50100381/…
Nikson
7

vous devez utiliser des boucles angular.forEach imbriquées pour JSON comme indiqué ci-dessous:

 var values = [
        {
            "name":"Thomas",
            "password":"thomas"
        },
        { 
            "name":"linda",
            "password":"linda"
        }];

    angular.forEach(values,function(value,key){
        angular.forEach(value,function(v1,k1){//this is nested angular.forEach loop
            console.log(k1+":"+v1);
        });
    });
Cerise
la source
1
Non, vous utiliseriez une seule boucle, et franchement, dans ce cas, vous devriez simplement utiliser le forEach () natif, à la values.forEach(object => console.log($ {object.name}: $ {object.password} )).
Kyle Baker
Changez simplement la ligne console.log (key + ':' + value); INTO console.log (clé + ':' + value.Name);
Israel Ocbina
5

Le angular.forEach()va parcourir votre jsonobjet.

Première itération,

clé = 0, valeur = {"nom": "Thomas", "mot de passe": "thomasTheKing"}

Deuxième itération,

clé = 1, valeur = {"nom": "Linda", "mot de passe": "lindatheQueen"}

Pour obtenir la valeur de votre name, vous pouvez utiliser value.nameou value["name"]. Même chose avec votre password, vous utilisez value.passwordou value["password"].

Le code ci-dessous vous donnera ce que vous voulez:

   angular.forEach(json, function (value, key)
         {
                //console.log(key);
                //console.log(value);
                if (value.password == "thomasTheKing") {
                    console.log("username is thomas");
                }
         });
nrs
la source
2

Changez la ligne en ceci

 angular.forEach(values, function(value, key){
   console.log(key + ': ' + value);
 });

 angular.forEach(values, function(value, key){
   console.log(key + ': ' + value.Name);
 });
Israël Ocbina
la source
2

Dans Angular 7, la boucle for est comme ci-dessous

var values = [
        {
            "name":"Thomas",
            "password":"thomas"
        },
        { 
            "name":"linda",
            "password":"linda"
        }];

for (let item of values)
{
}
sajadre
la source