0

I'm trying to find json object by a property/key from a complex/nested json array and replace it with other json object in an angular project.

I have used lodash to find json object by key but the json path of object can be anywhere on json array.

Here is my sample json array:

{
  "type": "form",
  "title": "title",
  "name": "name",
  "display": "form",
  "path": "path",
  "components": [
    {
      "mask": false,
      "tableView": true,
      "alwaysEnabled": false,
      "label": "",
      "rows": [
        [
          {
            "components": [
              {
                "key": "key1",
                "valueProperty": "value",
                "selectedKey": "ValueKey"
              }
            ]
          }
        ],
        [
          {
            "components": [
              {
                "components": [
                  {
                    "key": "key2",
                    "valueProperty": "value",
                    "selectedKey": "ValueKey"
                  }
                ],
                "allowMultipleMasks": false,
                "showWordCount": false,
                "showCharCount": false,
                "alwaysEnabled": false,
                "type": "textfield",
                "input": true,
                "widget": {
                  "type": ""
                }
              }
            ]
          }
        ],
        [
          {
            "components": [
              {
                "labelPosition": "left-left",
                "allowMultipleMasks": false,
                "showWordCount": false,
                "showCharCount": false,
                "alwaysEnabled": false,
                "input": true,
                "widget": {
                  "type": ""
                }
              }
            ]
          }
        ]
      ],
      "header": [],
      "numCols": 2
    }
  ]
}

I'm trying to find the entire json object if it contains "selectedkey" property and replace with other object.

Expected Result:

Json object { "key": "key1", "valueProperty": "value", "selectedKey": "ValueKey" } should be replaced with { "key": "key1", "valueProperty": "value", "selectedKey": "ValueKey" } 

Note: Json object can appear at n number of times and json path of object can be anywhere in json array.

1 Answers1

1

UPDATE: If you just want to check if that property exists, you can stringify the object and do an includes check, like this:

function containsKey(obj, key) {
    return JSON.stringify(obj).includes(key);
}

//OR

function containsKey(obj, key) {
    return JSON.stringify(obj).indexOf(key) !== -1;
}

You can use this to replace the whole object with a conditional block:

if (containsKey(obj, 'selectedKey')) {
    obj = otherObj;
}

ADDITIONAL SOLUTION: I also adapted my earlier solution that replaced the selectedKey to just check for the key. The advantage of this solution is that the function will return immediately after finding the selectedKey, as opposed to JSON.stringify, which will iterate over every property and value.

function containsKey(obj, targetKey) {

    // if the obj is an array, iterate it and call containsKey
    if (Array.isArray(obj)) {
        for (let i = 0; i < obj.length; i++) {
            return containsKey(obj[i], targetKey);
        }
    } else {
        // if it's not an array, it will be an obj
        let keys = Object.keys(obj);
        let key, value;

        // iterate the keys of the object
        for (let i = 0; i < keys.length; i++) {
            key = keys[i];
            value = obj[key];

            // if we find the target key, return true
            // otherwise, call containsKey on any objects
            if (key === targetKey) {
                return true;
            } else if (typeof value === 'object') {
                return containsKey(value, targetKey);
            }
        }
    }

    /* by this time we've checked every property of the object,
       so we know it does not contain the property or it would
       have returned true */
    return false;
}
  • Thanks Jordan for your response. As per my understanding, above code would replace the value of matched key in a json object but am trying to replace whole object with other object if it contains "selectedkey" key. – vishu krishna Apr 03 '19 at 05:11
  • I updated my solution to check for the existence of the property and added a conditional you can use to replace the object; is that more of what you were looking for? – Jordan Stubblefield Apr 03 '19 at 12:46