3

This is an update to my previous question Find and update in nested json object

Sample Data

TestObj = {
    "Categories": [{
        "Products": [{
            "id": "a01",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "id": "a02",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "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."
    }]
};

My Function

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] = newValue;
        }
    }
    return obj;
}

called as

getObjects(TestObj, 'id', 'A', 'B');

It works fine if I'm going to update id; since id don't have duplicates. But if I'm updating name all data matching key value pair is updated. But how to constrain it into a particular key-pair value.

What shall i provide to the function to constrain the update scope and how to implement it. Please help me.

Note: The json that I will b manipulating will be dynamically generated so I can't have any hard coded value in the function

6
  • 1
    Make values unique or break the loop once you found one (or a defined amount) Commented Aug 1, 2013 at 12:06
  • The values are dynamically generated so I can't, assure that it will be unique. Also I can't break the loop since I may have key-pair value in 1st child but have to update in 2nd child Commented Aug 1, 2013 at 12:11
  • 2
    How do you know which child should be updated? I mean, if you rely on key and value only, you have to update all matching pairs, but if you want to update just one of them then there should be an additional constraint. For example if the constraint is id, then it should be really easy to implement. Commented Aug 7, 2013 at 14:05
  • You can check whether input source from where you get data to update json is providing some other constraint on basis of which we can make different combination to update json. Commented Aug 7, 2013 at 14:30
  • I'm not sure I get the point of this function. What is your use case ? Commented Aug 7, 2013 at 16:13

1 Answer 1

7
+50

I think you can somehow use a path to locate the value and then do the update. I got the idea from this post. (answered by @shesek)

var getPath = function (obj, path, newValue) {
    var parts = path.split('.');
    while (parts.length > 1 && (obj = obj[parts.shift()]));
    obj[parts.shift()] = newValue;
    return obj;
}

console.log(getPath(TestObj, 'Categories.0.Products.1.id', 'AAA'))
console.log(TestObj)

So you can pass in the path to the object, for example, if you want to update the id of the following object to "AAA", you can pass in Categories.0.Products.1.id

    {
        "id": "a02",
        "name": "Pine",
        "description": "Short description of pine."
    }

then, the object will become

    {
        "id": "AAA",
        "name": "Pine",
        "description": "Short description of pine."
    }

Hope it can shed some light on!

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

4 Comments

The things is that the json is dynamically generated I won't be able to get the path.
gotcha, maybe you can generate the paths for json and send back as well?
thanks a lot. By far best solution after lot of search. very elegant.
I have used this code and it is creating new elements at the top level for some reason not updating.

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.