Knockout serialization with ko.toJSON - how to ignore properties that are null
Asked Answered
S

2

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??

Sapheaded answered 17/9, 2012 at 14:7 Comment(3)
Something to note, ko.toJSON does ignore values of undefined, see fiddle for examples. jsfiddle.net/Rynan/EnVmuStaphylorrhaphy
@Staphylorrhaphy - That is a useful observation. I didn't realise that so thanks.Sapheaded
ko.toJSON(myViewModel, (k, v) => v === null ? undefined : v)Lavinalavine
A
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;
        }
    }));
};
Academia answered 17/9, 2012 at 14:35 Comment(2)
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!Sapheaded
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 - cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.jsPheidippides
V
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.

Voroshilovsk answered 17/9, 2012 at 14:44 Comment(5)
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.Sapheaded
@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.Voroshilovsk
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 @Academia answer works globally with just a couple of lines of code which suits my situation better. +1 anyway for a useful approach.Sapheaded
This did exactly what I was looking for.Octal
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 "_" knockmeout.net/2011/04/…Chlodwig

© 2022 - 2024 — McMap. All rights reserved.