1

I read about how to iterate through a multi levels JSON object that contains both object and array in it using recursive technique.

Lets say the object in question is as follow

{
    "data":[
        {
            "Name": "Name1",
            "Id": "Id1",
            "Prop": {
                "isProp":""
                "isClass":"Yes"
            }
        },
        {
            "Name": "Name2",
            "Id": "Id2",
            "Prop": {
                "isProp":"No"
                "isClass":"Yes"
            }
        },
        {
            "Name": "Name3",
            "Id": "Id3",
            "Prop": [
                {
                    "isProp":"Maybe"
                    "isClass":""
                },
                {
                    "isProp":"No"
                    "isClass": null
                },
            ]
        }
    ]
}

Using the above as example, and if i want to change the empty or null value into a valid string, is below the right way to perform the recursive technique to iterate through the JSON object?

$.ajax(somethingHere).success(function(data){
    !(Array.isArray(data)) ? iterateObj(data) : $.each(data, function(){ iterateObj(this) });
});

function iterateObj(data){
    for(var key in data){
        if (data.hasOwnProperty(key)){
            if (!(Array.isArray(data[key]))){
                if (!data[key]){
                    data[key] = "Empty";
                }
            }
            else {
                $.each(data, function(){ iterateObj(this) })
            }
        }
    }
}

I tried the above but didn't work. Not sure where is my mistake tho. If possible, i'd like the function above to be able to iterate through any JSON object of any level and with/without object or array in it.

And i read somewhere that using Underscore/Lo-dash's pick/deepClone (not sure if i got it right) makes iteration (through any levels, and to any inner object/array inside the JSON object) much easier, is this true?

Thanks

2
  • 1
    Try to create a fiddle on this without the ajax call, using a fixed json format like the one shown here. Commented Sep 3, 2015 at 10:23
  • You might be thinking of underscore.js's trampoline which allows arbitrary levels of recursion without blowing the Javascript stack. Commented Sep 3, 2015 at 10:29

2 Answers 2

2

You are on the right way with your code. Only a few things to add:
- Recursive function should return the value
- Array.isArray(data[key]) is not a sufficient way to test for further iterations, use data[key] !== null && typeof data[key] === 'object' instead

So your function might look like this:

$.ajax(somethingHere).success(function(data){
    data = iterateObj(data);
});

function iterateObj(data) {
    for(var key in data){
        if (data.hasOwnProperty(key)) {
            if (data[key] !== null && typeof data[key] === 'object') {
                data[key] = iterateObj(data[key]);
            }
            else {
                if ( ! data[key]){
                    data[key] = "Empty";
                }
            }
        }
    }
    return data;
}

Also, your sample data object has invalid syntax (missing commas).

Sign up to request clarification or add additional context in comments.

2 Comments

I don't quite get the part where you're validating whether the key is an object or array. If that part is true, then wouldn't it skip iterating if the key being iterated is actually an array?
Arrays are also objects, so it would not skip. Since nulls are also considered as objects in Javascript - I am additionally checking whether the variable is not null.
0

Updated iterateObj() function to take care of other data types

function iterateObj(dupeObj) {
    var retObj = new Object();
    if (typeof (dupeObj) == 'object') {
        if (typeof (dupeObj.length) == 'number')
            var retObj = new Array();

        for (var objInd in dupeObj) {
            if (dupeObj[objInd] == null)
                dupeObj[objInd] = "Empty";
            if (typeof (dupeObj[objInd]) == 'object') {
                retObj[objInd] = iterateObj(dupeObj[objInd]);
            } else if (typeof (dupeObj[objInd]) == 'string') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof (dupeObj[objInd]) == 'number') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof (dupeObj[objInd]) == 'boolean') {
                ((dupeObj[objInd] == true) ? retObj[objInd] = true : retObj[objInd] = false);
            }       
        }
    }
    return retObj;
}

1 Comment

I'm not sure if checking other data types (other than object and array, and possibly boolean) are necessary, since i just want to change any empty data (empty, NaN, undefined, null, 0, false..) to "Empty".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.