nghs
nghs

Reputation: 149

Find and update a specific object in JSON

I am generating a form that is constructed from JSON. I've successfully created the form, but I am now trying to figure out how to update the specific item in JSON from the user input. I've seen this question asked using node and underscore, etc but I would like to accomplish this with vanilla JS or jQuery.

I am trying to avoid modifying the JSON other than the values as it will need to be sent back in the same format, and I am able to find an item by its key or value, however the problem I have is that there are multiple k/v pairs in each object that I am using. Here is an example object:

var list = {
"parent": {
   "item" : {
      "id" : "a1b295",
      "name" : "sample name",
      "value" : "this is a sample value"
   }
}

My form elements come out as <input type="text" name="a1b295" value="this is a sample value" />

What I am trying to do is on submit, iterate through the form elements and update each object in the JSON. I am struggling to figure out how to look up the item by its id and then update the value key value pair for that object.

To be clear the data can have any number of nested children, and I need to go after the ones with specific IDs which I am already turning into form inputs.

Thank you.

This is what I have attempted but it returns a "can't access id of undefined" error.

function traverseData(data, obj)
  {
      for (var k in data)
      {
          if (typeof data[k] == "object" && data[k] !== null) {
              traverseData(obj[k], obj);
          } else if (!data.hasOwnProperty(k)) {
            continue;
          } else if (k = obj) {
            console.log(obj);
          }
      }
  }

  traverseData(data, $(this).attr('id'));

Upvotes: 0

Views: 2110

Answers (4)

MEDZ
MEDZ

Reputation: 2295

Javascript now supports for..in where you can loop through object keys:

let data = {
  "item" : {
     "id" : "a1b295",
     "name" : "sample name",
     "value" : "this is a sample value"
  }
};


function traverseData(data, obj, newValue)
  {
      for (var k in data)
      {
          if (data.hasOwnProperty(k) && typeof data[k] == "object") {
              data[k] = traverseData(data[k], obj, newValue);
          } else if (k == obj) {
            console.log(obj);
            data[k] = newValue;
          }
      }
      return data
  }

//single element
$('input').blur(function(event){
   data = traverseData(data, 'value', $(this).attr('value'));
   console.log(data);
});

//multiple elements
$('input').each(function (index) {
   let self = $(this); //to differenciate between elements
   self.blur(function(event){
      data = traverseData(data, 'value', $(this).attr('value'));
      console.log(data);
   });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" name="a1b295" value="this is a sample value 2" />

Upvotes: 0

Nick Katunov
Nick Katunov

Reputation: 11

I assume you have an array of objects. So you basically can filter this array to find the object of which the id matches the corresponding input's name. And then update this object's value property with the input value.

  const targetInput = document.getElementById('inputId')
  let newValue = targetInput.value
  let inputName = targetInput.name
  // We filter objects to find the one where id matches input's name
  let targetObject = objects.filter(i => i.item.id === inputName)
  targetObject[0].item.value = newValue
  console.log(targetObject)

Upvotes: 0

Sunny Patel
Sunny Patel

Reputation: 8078

If I understand your question correctly, you have your form which was generated from a JSON array in the format described above, and want to update the values in that JSON array with new values that may have changed on submission.

The following code assumes your forms have been set up properly, and the text values have been updated with the values in the HTML section.

jQuery solution

const json = [
  {
    "item": {
      "id": "a1b295",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b296",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b297",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b298",
      "name": "sample name",
      "value": "this is a sample value"
    }
  }
]

for (const item in json) {
  json[item].item.value = $('input[name="' + json[item].item.id + '"]').val()
}
console.log(json)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="a1b295" value="this is a sample value" />
<input type="text" name="a1b296" value="New sample value1" />
<input type="text" name="a1b297" value="New sample value2" />
<input type="text" name="a1b298" value="New sample value3" />

Vanilla Javascript solution

const json = [
  {
    "item": {
      "id": "a1b295",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b296",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b297",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b298",
      "name": "sample name",
      "value": "this is a sample value"
    }
  }
]

for (const item in json) {
  json[item].item.value = document.querySelector('input[name="' + json[item].item.id + '"]').value
}
console.log(json)
<input type="text" name="a1b295" value="this is a sample value" />
<input type="text" name="a1b296" value="New sample value1" />
<input type="text" name="a1b297" value="New sample value2" />
<input type="text" name="a1b298" value="New sample value3" />

These examples overwrite the value in the json variable that you can submit with your form. You should see that the json values have been updated to those in the HTML.

Upvotes: 2

Dressy Fiddle
Dressy Fiddle

Reputation: 163

If I understand correctly, you could before submitting to json alter the input string and change values accordingly.

If u need to compare to another JSON u could just compare values via function.

JSON is just a formated string.

Upvotes: 0

Related Questions