Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and update in nested json object

I used this code to find the required portion from the json object from sJhonny's Question

Data Sample

TestObj = {
    "Categories": [{
        "Products": [{
            "id": "a01",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "id": "a02",
            "name": "Birch",
            "description": "Short description of birch."
        },
        {
            "id": "a03",
            "name": "Poplar",
            "description": "Short description of poplar."
        }],
        "id": "A",
        "title": "Cheap",
        "description": "Short description of category A."
    },
    {
        "Product": [{
            "id": "b01",
            "name": "Maple",
            "description": "Short description of maple."
        },
        {
            "id": "b02",
            "name": "Oak",
            "description": "Short description of oak."
        },
        {
            "id": "b03",
            "name": "Bamboo",
            "description": "Short description of bamboo."
        }],
        "id": "B",
        "title": "Moderate",
        "description": "Short description of category B."
    }]
};

Function to find

function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}

Use like so:

getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects

This code is to select matching piece from the source. But what I want is to update the source object with new value and retrieve the updated source object.

I want something like

getObjects(TestObj, 'id', 'A', 'B'); // Returns source with updated value. (ie id:'A' updated to id:'B' in the returned object)

My code

function getObjects(obj, key, val, newVal) {
    var newValue = newVal;
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            obj[key] = 'qwe';
        }
    }
    return obj;
}

This works if i give obj[key] = 'qwe'; but if i change the code into obj[key] = newValue; its updated as undefined.

Why is that so?

like image 255
Okky Avatar asked Aug 01 '13 08:08

Okky


People also ask

Does JSON Stringify work on nested objects?

If your deeply-nested object or array only includes certain primitive values (strings, numbers, boolean, and null), then you can use JSON. parse() & JSON. stringify() to deep copy without issues.

What does JSON Stringify () do?

The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.


2 Answers

You forgot to pass newValue in the nested call

function getObjects(obj, key, val, newVal) {
    var newValue = newVal;
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val, newValue));
        } else if (i == key && obj[key] == val) {
            obj[key] = 'qwe';
        }
    }
    return obj;
}
like image 106
Jetson John Avatar answered Oct 19 '22 20:10

Jetson John


This ?

function update(obj, key, newVal) {
    for(var i in obj) {
        if(typeof obj[i] == 'object') {
            update(obj[i], key, newVal));
        } else if(i === key) {
            obj[i] = newVal;
        }
    }
    return obj;
}
like image 36
Virus721 Avatar answered Oct 19 '22 19:10

Virus721