18

When using:

var dataToSave = ko.toJSON(myViewModel);

.. is it possible to not serialize values that are null?

Serializing my current viewModel creates around 500Kb of JSON most of which is ends up like:

"SomeObject": {
    "Property1": 12345,
    "Property2": "Sometext",
    "Property3": null,
    "Property4": null,
    "Property5": null,
    "Property6": null,
    "Property7": null,
    "Property8": null,
    "Property9": false
}

If I could get the serializer to ignore null values then this could be reduced down to:

"SomeObject": {
    "Property1": 12345,
    "Property2": "Sometext",
    "Property9": false
}

Any ideas how I can instruct the serializer to ignore the null values??

Mark Robinson
  • 13,128
  • 13
  • 63
  • 81

2 Answers2

33

Remember that ko.toJSON is just a modification of JSON stringify. You can pass in a replacer function.

As an example of using a replacer function in Knockout, I put together a JSFiddle based on one of the knockout tutorials. Notice the difference between the makeJson and makeCleanJson functions. We can choose not to return any values in our replacer function and the item will be skipped in the JSON string.

self.makeJson = function() {
    self.JsonInfo(ko.toJSON(self.availableMeals));
};

self.makeCleanJson = function() {
    self.JsonInfo(ko.toJSON(self.availableMeals, function(key, value) {
        if (value == null)
        {
            return;
        }
        else
        {
            return value;
        }
    }));
};
deltree
  • 3,756
  • 1
  • 30
  • 51
  • 1
    Great answer, deltree. And thanks for the jsFiddle. The only change I made was to use 'value === null' instead of 'value == null' just to be extra sure! – Mark Robinson Sep 17 '12 at 15:25
  • thanks for this answer, will try it out soon ... just wanted to let you know that the ref to ko in the jsFiddle is dead. Used this instead - http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js – David Perlman Aug 20 '13 at 16:38
16

You can add a toJSON method to your view model and use that to remove all the unneeded properties:

 ViewModel.prototype.toJSON = function() {
     var copy = ko.toJS(this);
     // remove any unneeded properties
     if (copy.unneedProperty == null) {
         delete copy.unneedProperty;
     }
     return copy;
 }

You could probably automate it to run through all your properties and delete the null ones.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • Thanks for the answer Matt but I think this works more if the property should NEVER be converted to JSON rather than in my case where I only want to convert the property to JSON when its value is not null. – Mark Robinson Sep 17 '12 at 15:28
  • 2
    @MarkRobinson: Not so, you check if it's null, and only delete it if it is. I'll edit my answer to make this clear. – Matt Burland Sep 17 '12 at 18:14
  • 1
    Thanks for the clarification, Matt. The amended approach would work. The advantage of your approach seems to be it offers more fine grain control over which properties have their null values ignored but @deltree answer works globally with just a couple of lines of code which suits my situation better. +1 anyway for a useful approach. – Mark Robinson Sep 18 '12 at 07:26
  • This did exactly what I was looking for. – Nick Aug 14 '14 at 22:43
  • This seems a much better answer, as it will work transparently for all consumers using the standard ko.toJSON. I'm using this approach, which is explained in the following article, adding the convention of ignoring all properties which start by underscore "_" http://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html – Francesc Castells Oct 01 '15 at 12:56