I want to convert viewModel to Json object. But I don't want to map computed properties.
2 Answers
Here are a few options, if you are going to convert it to JSON:
if you are using constructor functions for your object, then you can override the
.toJSON
function to control which properties to output. Here is an article on it: http://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html. Here is a sample: http://jsfiddle.net/rniemeyer/FE4HX/.in KO 2.1, when using
ko.toJSON
the second and third arguments are now passed toJSON.stringify
. Here is some documentation on the arguments: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify. This means that you can pass the second argument (replacer
) with either an array of properties to include or a function that processes the key/values. Here is the same sample using this technique: http://jsfiddle.net/rniemeyer/huyLe/.Another option that I use frequently, is to define computeds that you don't want in your JSON output as sub-observables. Observables are functions, which are objects, so you can actually define observables on observables. Like:
-
this.name = ko.observable("Bob");
this.name.formatted = ko.computed(...);
Now when converting to JSON, formatted
will be naturally lost as name
gets converted to its value. Here is the same sample again: http://jsfiddle.net/rniemeyer/peEGG/. Usually I use this when it is meta-data about an observable (isValid
, isEditing
, etc.).

- 33,529
- 30
- 159
- 234

- 114,592
- 18
- 291
- 211
-
3That third option saved my ass. I love you, Niemeyer. – SoreThumb Dec 30 '12 at 00:01
-
Similar to José Angel Yánez answer below, here's a way to use a replacer method like in 2nd option above, but to create an JSON object (like ko.toJS): ko.toJS2 = function (model, replacer) { return JSON.parse(ko.toJSON(model, replacer)); } – David Russell Nov 04 '13 at 11:57
-
1Wish I knew the third one earlier! Thank you, Niemeyer. – Maximilian Lindsey Feb 26 '14 at 15:47
-
let me add my name to the list of those loving the sub-observable. thanks very many. – Dave Rael Aug 03 '14 at 19:57
-
Third option should be the first one, till now I didn't think about it even though I am using validation plugin which uses same approach for isValid function – Nish Mar 25 '15 at 12:41
-
Lol @Niemeyer, the third option saved me.. don't know how in the world you came up with the fact that the mapping plugin would ignore that sub-observable but thanks! – Benjamin Vison Jan 25 '16 at 17:55
-
2I know we're not supposed to tack on with "me too" comments... but option #3 is so slick that I spontaneously just said to my coworkers that I "heart" Ryan Niemeyer. – Nate Jackson Apr 07 '16 at 16:30
-
the #3 is really witty, but quite ugly in terms of design I think customizing the serializer is a better approach. (but I need to admit it's tempting) – mikus Feb 14 '17 at 17:13
This will also work, it will just ignore anything with a 'mappedProperties' in it, for duck-type naysayers remember you shouldn't have mappedProperties as part of your code since you're using knockout. Therefore it should work.
/* Use this serializer function along with ko.toJS to produce clean JSON objects. */
ko.toJS2 = function (model)
{
return JSON.parse(ko.toJSON(model, modelSerializer));
}
function modelSerializer(key, value)
{
if (isSerializable(value))
return value;
else
return;
}
function isSerializable(object) {
if (object == null) return true;
if (typeof object == 'function') return false;
if (object.mappedProperties != null) return false;
return true;
}
Usage:
var goodLookingJson = ko.toJS2(whateverModel);

- 161
- 1
- 2
-
Thanks, hat-tip for posting code! Just to clarify, your `ko.toJS2` function returns pure javascript objects, not JSON strings, right? Would you just strip out the JSON.parse call to create a `ko.toJSON2` (or `ko.toCleanJSON` as I'd call it)? – aaaidan Jul 21 '13 at 03:53