JSON.stringify is ignoring object properties

20.4k views Asked by At

See the jsfiddle example http://jsfiddle.net/frigon/H6ssq/

For some reason there are fields that JSON.stringify is ignoring. Is there a way to force JSON.stringify to parse them?

As the jsfiddle shows... this code...

<script src="http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"></script>
    <script>
    var model = kendo.data.Model.define({id: "ID", fields: {"Name":{type: "string"}}});
    var obj = new model();
    obj.set("Name","Johhny Foosball");
    document.write("<br />obj.dirty property exists: ");
    document.write(obj.dirty);
    document.write("<br/>obj.uid property exists: ");
    document.write(obj.uid);
    document.write("<br/>But they dont show in JSON.stringify():<br/>");    
    document.write(JSON.stringify(obj));
</script>

will output:

obj.dirty property exists: true

obj.uid property exists: b4af4dfc-9d94-4a2d-b286-d6f4cbc991d8

But they dont show in JSON.stringify():

{"ID":"","Name":"Johhny Foosball"}

4

There are 4 answers

0
Kevin Babcock On BEST ANSWER

When an object has its own toJSON() implementation, JSON.stringify() uses the object returned from that method and stringifies that. kendo.data.Model defines it's own toJSON() method which only returns the properties defined on the model, which is why you aren't seeing other values (e.g. dirty, id, uid) in the string result.

"If the stringify method sees an object that contains a toJSON method, it calls that method, and stringifies the value returned. This allows an object to determine its own JSON representation."

Here's an alternative if you must have all properties on the object:

var model = kendo.data.Model.define({
    id: "ID",
    fields: {
        "Name": { type: "string" }
    }
});
var obj = new model();
obj.set("Name","Johhny Foosball");    
var newObj = $.extend({}, obj);
delete newObj.toJSON;
document.write(newObj.dirty);
document.write(JSON.stringify(newObj));

..and the updated fiddle.

Basically I used jQuery.extend to clone the object then deleted the toJSON function. Use at your own risk! :)

3
Nikos Papageorgiou On

Somewhat relevant, as I came here looking for a solution to a similar situation: For those looking for a way to get back their original object, before kendo added all sorts of weird hidden properties to it, do:

cleanObject = JSON.parse(JSON.stringify(kendoDataItem));

I encountered this scenario when I needed to pass the selected item from the kendo tree to a json-formatter directive. But what do you know, kendo had allready messed up with my original object.

<div kendo-tree-view="tree" k-data-source="treeData" k-on-change="selectedItem=dataItem">
    {{dataItem.text}}
</div>

<json-formatter open="1" json="selectedItem"></json-formatter>
0
Berty On

If you're working in NodeJS you can use:

import * as util from 'util';
util.inspect(obj)

instead of JSON.stringify

0
User1 On

It is using its own JSON.stringify method. This has happened to me with Sequelize. I stringify the object before adding the new property like this:

objStringified = JSON.stringify(obj) // uses its own JSON.stringify method
obj = JSON.parse(objStringified) // only shows properties specified as columns in its model
obj.dirty = "whatever";
finalObj = JSON.stringify(objParsed); // now it doesn't have its own JSON.stringify method, so dirty property appears