bucle foreach en angularjs

110

Yo estaba pasando por la forEach loopde AngularJS. Hay algunos puntos que no entendí al respecto.

  1. ¿Cuál es el uso de la función de iterador? ¿Hay alguna forma de prescindir de él?
  2. ¿Cuál es el significado de la clave y el valor que se muestran a continuación?

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

PD: intenté ejecutar esta función sin los argumentos y no funcionó.

Aquí está mi json:

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

Mi JavaScriptarchivo:

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

Otra pregunta : ¿Por qué la función anterior no ingresa en if condición e imprime "nombre de usuario es thomas" en la consola?

Pragam Shrivastava
fuente
6
Porque no está esperando successque suceda su $http.get(), por lo tanto, cuando angular.forEach()suceda, $scope.dataaún no está definido.
Tom
1
¿Hay alguna forma específica de mantener la ejecución del código hasta que se cargue el json?
Pragam Shrivastava
Cambie la línea a este angular.forEach (valores, función (valor, clave) {consola.log (clave + ':' + valor.Nombre);});
Israel Ocbina

Respuestas:

208

Preguntas 1 y 2

Entonces, básicamente, el primer parámetro es el objeto sobre el que iterar. Puede ser una matriz o un objeto. Si es un objeto como este:

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

Angular tomará cada valor uno por uno, el primero es el nombre, el segundo es el género.

Si su objeto para iterar es una matriz (también es posible), así:

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

Angular.forEach tomará uno por uno comenzando por el primer objeto, luego el segundo objeto.

Para cada uno de estos objetos, los tomará uno por uno y ejecutará un código específico para cada valor. Este código se llama función de iterador . forEach es inteligente y se comporta de manera diferente si está utilizando una matriz de una colección. A continuación se muestra un ejemplo:

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

Entonces, la clave es el valor de cadena de su clave y el valor es ... el valor. Puede usar la clave para acceder a su valor de esta manera:obj['name'] = 'John'

Si esta vez muestra una matriz, como esta:

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]

Entonces el valor es su objeto (colección), y la clave es el índice de su matriz ya que:

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

Espero que responda a tu pregunta. Aquí hay un JSFiddle para ejecutar algún código y probarlo si lo desea: http://jsfiddle.net/ygahqdge/

Depurando tu código

El problema parece provenir del hecho de que $http.get()es una solicitud asincrónica.

Envías una consulta sobre tu hijo, ENTONCES , cuando el navegador termina de descargarlo, se ejecuta correctamente. PERO justo después de enviar su solicitud, realiza un ciclo usando angular.forEachsin esperar la respuesta de su JSON.

Debe incluir el bucle en la función de éxito

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

});

Esto debería funcionar.

Yendo mas profundo

La API $ http se basa en las API diferidas / promesas expuestas por el servicio $ q. Mientras que para patrones de uso simples esto no importa mucho, para uso avanzado es importante familiarizarse con estas API y las garantías que brindan.

Puede echar un vistazo a las API diferidas / prometidas , es un concepto importante de Angular para realizar acciones asincrónicas sin problemas.

sebastienbarbier
fuente
2
Colin B (perfil aquí .) Quería comentar eso successy error han sido desaprobados . Se sugiere utilizar el thenmétodo en lugar de success. ¡Ahora, @ Colin, sal y responde algunas preguntas para obtener 50 repeticiones! : P
Drew
3
Async no es paralelo. Para el paralelo, necesitará webworkers, no promesas. Un poco pedante, pero vale la pena detener la desinformación cada vez que sucede.
Kyle Baker
1
Gracias @KyleBaker, actualicé esta respuesta, tienes razón "paralelo" fue un abuso de lenguaje.
sebastienbarbier
@sebastienbarbier, ¿pueden ayudarme a resolver esto? stackoverflow.com/questions/50100381/…
Nikson
7

tienes que usar bucles angulares.forEach anidados para JSON como se muestra a continuación:

 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);
        });
    });
Cereza
fuente
1
No, usaría un solo bucle y, francamente, en este caso, solo debe usar el nativo forEach (), a la values.forEach(object => console.log($ {object.name}: $ {object.password} )).
Kyle Baker
Simplemente cambie la línea console.log (clave + ':' + valor); INTO console.log (clave + ':' + valor.Nombre);
Israel Ocbina
5

El angular.forEach()iterará a través de su jsonobjeto.

Primera iteración,

clave = 0, valor = {"nombre": "Thomas", "contraseña": "thomasTheKing"}

Segunda iteración,

clave = 1, valor = {"nombre": "Linda", "contraseña": "lindatheQueen"}

Para obtener el valor de su name, puede usar value.nameo value["name"]. Lo mismo con tu password, usas value.passwordo value["password"].

El siguiente código le dará lo que desea:

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

Cambia la línea en esto

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

 angular.forEach(values, function(value, key){
   console.log(key + ': ' + value.Name);
 });
Israel Ocbina
fuente
2

En Angular 7, el bucle for es como el siguiente

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

for (let item of values)
{
}
sajadre
fuente