Oxossi
Oxossi

Reputation: 117

Loop through object with nested $.each

I'm having trouble looping through an object using a nested $.each. The object is a series of object of the same type/class nested under rootObject.

The object

var rootObject ={};

rootObject.reportObject1.name = "reportObject1 Name";
rootObject.reportObject1.prop1 = "reportObject1 Prop1_Value";
rootObject.reportObject1.prop2 = "reportObject1 Prop2_Value";

rootObject.reportObject1.reportObjectA.name = "reportObjectA Name";
rootObject.reportObject1.reportObjectA.prop1 = "reportObjectA Prop1_Value";
rootObject.reportObject1.reportObjectA.prop2 = "reportObjectA Prop2_Value";

The Loop

$.each(rootObject, function(index0, value0){
  console.log(value0.name);

  $.each(value0, function(index1, value1){
    console.log(value1.name);
  }

}

The Problem

  1. value1.name is returning object properties other than name in the loop. It's seemingly attempting to return value.name for prop1 & prop2, resulting in "undefined" values.

  2. When looking into the value of value0 during debugging, value0 appears to loose its value as it enters the nested loop. I.e at console.log(value1.name), value0, from the parent loop, becomes undefined;

  3. When looking into the child loop (index1, value1) during debugging, I see that value1 now equals value0.name, and index1 equals "name".

Upvotes: 0

Views: 55

Answers (1)

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107536

You can automatically define properties one level deep, but for two you need to stop and instantiate the parent:

var rootObject ={};

rootObject.reportObject1 = {}; // HERE
rootObject.reportObject1.name = "reportObject1 Name";
rootObject.reportObject1.prop1 = "reportObject1 Prop1_Value";
rootObject.reportObject1.prop2 = "reportObject1 Prop2_Value";

rootObject.reportObject1.reportObjectA = {}; // and HERE
rootObject.reportObject1.reportObjectA.name = "reportObjectA Name";
rootObject.reportObject1.reportObjectA.prop1 = "reportObjectA Prop1_Value";
rootObject.reportObject1.reportObjectA.prop2 = "reportObjectA Prop2_Value";

Without that, none of these properties are actually getting defined, leading to your undefined results.

The next issue is another syntax problem: you're missing closing parentheses on the two $.each() calls:

$.each(rootObject, function(index0, value0){
  console.log(value0.name);

  $.each(value0, function(index1, value1){
    console.log(value1.name);
  }); // HERE

}); // and HERE

With these two fixes, your console output shows:

reportObject1 Name
undefined (x3)
reportObjectA Name

To get the correct output, or at least some sample output, you could use this little gem (from here). Because your structure could potentially have more than two levels, recursion seems appropriate here.

function enumerate(o,s){

    //if s isn't defined, set it to an empty string
    s = typeof s !== 'undefined' ? s : "";

    //iterate across o, passing keys as k and values as v
    $.each(o, function(k,v){

        //if v has nested depth
        if(typeof v == "object"){

            //write the key to the console
            console.log(s+k+": ");

            //recursively call enumerate on the nested properties
            enumerate(v,s+"  ");

        } else {

            //log the key & value
            console.log(s+k+": "+String(v));
        }
    });
}

If you try enumerate(rootObject), you will get:

reportObject1: 
   name: reportObject1 Name
   prop1: reportObject1 Prop1_Value
   prop2: reportObject1 Prop2_Value
   reportObjectA: 
     name: reportObjectA Name
     prop1: reportObjectA Prop1_Value
     prop2: reportObjectA Prop2_Value

Upvotes: 2

Related Questions