JSON object properties display as "0" in javascript - javascript

I have some server side methods returning a JSON object that my JS parses and tries to enumerate through the properties to set the input with the same name as the property value. My application is in ASP.Net MVC 5 and I got the JSON working correctly.
Here is my JS:
function ProcessPropertyChange(url, name)
{
var val = $("[name='" + name + "'").val();
url = url + "&propValue=" + val;
$.get(url, function (data) {
var obj = JSON.parse(data);
for (var prop in obj)
{
if(obj.hasOwnProperty(prop))
{
$("[name='" + prop + "'").text = obj[prop];
alert(prop);
}
}
});
}
An example JSON string would be:
[{"FullAddress" : "123 w. oak", "ParentName":""}]
That was taken from my code.
When I view my object in the developer's console I can see the properties with the proper names, FullAddress and ParentName, however when I try to enumerate through them it returns "0" and the value of obj[prop] is always [Object object].
Any ideas? Can post more code if you need.
Thanks!

obj is an array which has an object as its member, so the object has indexes 0...length-1 that is why you are getting 0.
If you are expecting the array to have only 1 value, then instead of returning an array return the object, else in your js code read the object from the 0th index of the data. Also you can use $.each() like
$.get(url, function (data) {
//since data is an array
var obj = data[0];
$.each(obj, function (value, prop) {
$("[name='" + prop + "'").text = value;
alert(prop);
})
}, 'json');

Related

javaScript: Parsing a stringified object with JSON.parse removes references

I am trying to deep-clone an object, say "a" with k = JSON.parse(JSON.stringify(a)). It is important that I use the stringify way, since I am trying to save the object into a file and then load from it.
I stumbled upon a problem with references on the cloned object which is illustrated below:
var obj={};
obj.importantProperty={s:2};
obj.c=obj.importantProperty;
obj.d=obj.importantProperty;
console.log( obj.c === obj.d ); // Returns true
var cloned = JSON.parse(JSON.stringify(obj));
console.log( cloned.c === cloned.d ); // Returns false
I need the references to be kept when using JSON.parse, in the above example they are not. In my project the object is much more complicated, but in the end it comes down to the example above.
Thanks in advance to anyone who helps me with this :)
The proper way to do something like this would be to store the common referenced object(s) separately and reference it by an ID.
For instance, you can hold your importantProperty objects in an array and use the index as the ID:
var importantProperties = [
{ s: 1 },
{ s: 2 },
{ s: 3 }
];
var obj = {};
obj.importantProperty = importantProperties[1];
obj.c = obj.importantProperty;
obj.d = obj.importantProperty;
Then when you stringify the object you replace the referenced object with its index:
var stringified = JSON.stringify(obj, function(key, value) {
if (key) {
return importantProperties.indexOf(value);
}
return value;
});
console.log(stringified);
// prints {"importantProperty":1,"c":1,"d":1}
And then when you parse you simply reverse the process to revive the references:
var parsed = JSON.parse(stringified, function(key, value) {
if (key) {
return importantProperties[value];
}
return value;
});
console.log(parsed.c === parsed.d && parsed.d === parsed.importantProperty);
// prints true
Now, the example above works for your example code under the assumption that all properties in obj is an object from the importantProperties array. If that's not the case and it's only certain properties that is an importantProperties object, you need to check for that when replacing/reviving.
Assuming only the "importantProperty", "c" and "d" properties are such objects:
if (['importantProperty', 'c', 'd'].includes(key)) instead of just if (key)
If this isn't good enough and you don't want the property name to have anything to do with whether or not the value is an importantProperties object, you'll need to indicate this in the value together with the identifier. Here's an example of how this can be done:
// Replacing
JSON.stringify(obj, function(k, value) {
if (importantProperties.includes(value)) {
return 'ImportantProperty['
+ importantProperties.indexOf(value)
+ ']';
}
return value;
});
// Reviving
JSON.parse(stringified, function(k, value) {
if (/^ImportantProperty\[\d+\]$/.test(value)) {
var index = Number( value.match(/\d+/)[0] );
return importantProperties[index];
}
return value;
});
It is impossible to achieve your desired result using JSON because JSON format can contain only a limited ammount of data types (http://json.org/) and when you stringify an object to JSON some information gets lost.
Probably there is some other kind of serialization technique, but I would recommend you to look for another approach to store data.

how to access a multilevel key/value from an object within another object

So for instance if I the following two objects
var person = {};
person.name = 'Austin';
person.personality = 'Awsome';
var job = {};
job.title = 'space cowboy';
job.pay = 10,000;
person.job = job;
and I want to programmatically list each key and value par in a for loop I have the following
for(var key in person){
console.log(key)
console.log(person.key)
}
How would I be able to detect in this loop when key reaches job without hardcoding if person.key == job. Also how would i list out all of jobs keys from within this for loop?
function trace(ob){
for (var item in ob){
if (typeof ob[item] == 'object') trace(ob[item]);
console.log("key", item);
console.log("value", ob[item]);
}
}
You could obviously do a lot about the formatting, but here's a simple example of walking through the object recursively. Maybe it'll help show you what you need to do:
function iterate(object) {
for(var key in object) {
if (object[key] instanceof Object) {
iterate(object[key]);
}
else {
console.log(key + ": " + object[key]);
}
}
}
Here's an example if it helps: http://jsbin.com/AmUkIPO/2/
You could this instead:
how would i list out all of jobs keys
var keys = Object.keys(person.job); // get the all the properties keys as array.
keys.map(function(prop, index){
//prop is a propery
// index: the index position in the array
// prop === "property named"
});
How to get the values and compared them:
for (prop in person) {
if (person[prop] === someValue){
..
}
}
*someValue: means a value in case you want to search for something else other than just getting the value type.
All together:
for (prop in person) {
if (person[prop] === someValue){
var keys = Object.keys(person[prop]); // get the all the properties keys as array.
}
}

Accessing JavaScript object via key

I have a JavaScript object called data. I am using the following code to sort the keys in the object :
var index = [];
// build the index
for (var x in data) {
index.push(x);
}
// sort the index
index.sort(function (a, b) {
return a == b ? 0 : (a > b ? 1 : -1);
});
I then want to access the value for a particular index key in the following way :
for (var i=0; i<index.length; i++) {
var key = index[i];
document.getElementById(key).value = data.key;
}
However I am getting undefined for the data.key value. Can anyone suggest why ?
Change to
document.getElementById(key).value = data[key];
If the key you want to access is stored within a variable, you have to use the bracket notation. In your code, JavaScript will search for a key named "key" and thus fails.
Example:
var key = 'test';
console.log( data.key ); // yields content of data.key
console.log( data[key] ); // yields content of data.test
How about
Object.keys(data)[key] ?
Not sure it would work, without showing the structure of data.
edit: This way retrieves object key according to numerical index (0,1...,n), and not by name.

Finding value in json string

Below is what I have as JSON String.
{
"ID_A0001":{"areaID":"A0001","shopID":"SH004","quantity":14},
"ROW_INFO":{"areaID":"VARCHAR","shopID":"VARCHAR","quantity":"INT"},
"ID_A0002":{"areaID":"A0002","shopID":"SH008","quantity":18}
}
What I want is to get the JSONObject which have ID as ID_A i.e. ID_A0001 & ID_A0002.
I was thinking of using jsonObject.getString("ID_A"), but that is not possible. Could someone tell me what should I do so that I will get as below output.
{
"ID_A0001":{"areaID":"A0001","shopID":"SH004","quantity":14},
"ID_A0002":{"areaID":"A0002","shopID":"SH008","quantity":18}
}
The following code does what you want, assuming the object you posted is stored in obj. In case you actually have a JSON string instead of an object, use JSON.parse() to convert the string to a JavaScript object.
var obj2 = {};
for(var key in obj) {
if(key.substr(0, 4) == 'ID_A') {
obj2[key] = obj[key];
}
}
In the json object you have mentioned, you can modifiy it as follows.
var jsontest={
ID_A0001:{"areaID":"A0001","shopID":"SH004","quantity":14},
ROW_INFO:{"areaID":"VARCHAR","shopID":"VARCHAR","quantity":"INT"},
ID_A0002:{"areaID":"A0002","shopID":"SH008","quantity":18}
};
for(var key in jsontest) {
if(key.substring(0,4)=='ID_A')
alert('key: ' + key + '\n' + 'value: ' + jsontest[key].areaID);
}
http://jsfiddle.net/FBLvP/
Here is a useful link which shows us how to get the list of keys from a json object
http://encosia.com/using-jquery-1-6-to-find-an-array-of-an-objects-keys/1

Javascript function push problem

i've following JS function.
responseData:function(resp){
this.jsondata = eval('(' + resp + ')');
this.propList = [];
for (var i = 0;i<this.jsondata.length;i++) {
for (obj in this.jsondata[i]) {
alert(obj); //shows the property name of obj
this.propList.push({
obj : this.jsondata[i][obj] //insert only simple obj string
});
}
}
return this.propList;
}
I want to insert in my propList the property name and the value, but instead inserting the property name this function inserts simple 'obj' as a string. What i'm doing wrong?
greetings
Stefan
Change the loop to,
for (obj in this.jsondata[i]) {
alert(obj); //shows the property name of obj
var item = {};
item[obj] = this.jsondata[i][obj];
this.propList.push(item);
}
When you use object-literal to create an object the property names are not evaluated as variables. To specify the name of an objects property using a variables current value, you must use the obj[variable] format. This will create a property within obj whose name will be the same as current value of variable.

Categories