1

I've been using knockout.js for months now and only just realized it invokes functions when calling ko.toJS when serializing my model.

This can lead to obvious problems like infinite loop, and at worst dangerous data corruption if a function with side effects is being called.

This behavior was at one point changed in an earlier version of Knockout, but it seems it was backtracked upon as being by design because sometimes some people want functions to be copied.

Well I never do (I don't think I do) and I'd really appreciate a way to be able to call toJS that would not invoke my functions.

I realize I can use toJSON instead but sometimes you really do want toJS in the case where you want to do something like this:

toJSON = () =>     // this is typescript syntax
{
     var copy = ko.toJS(this);

     // remove credit card details if not selected payment type
     if (this.paymentType() != 'CreditCard')
     {
         delete copy.creditCardDetails;
     }

     return copy;
}

Or perhaps I'm passing the model to some utility method that needs objects.

I guess I ultimately don't understand why the invocation of functions on my viewmodel isn't configurable and if there's an easy way to 'monkey patch' it or create a new toJS2 function then I'd really like to be able to do that.

There is some very useful information in this question, How can I use ko.toJs method without computed properties in knockout mapping? but as yet I've found no solution if I want to retain objects rather than convert to a string.

Community
  • 1
  • 1
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689

2 Answers2

4

For future reference (and I've encountered the same issue at times), you can create a mapping to ignore methods:

var mapping = {
    'ignore': ['load', 'reset', 'onSubmit']
};
var data = ko.mapping.toJS(object, mapping);
Paul Manzotti
  • 5,107
  • 21
  • 27
  • thanks. this is trickier when you have an object graph like I do - I construct 'objects' for each element in the viewmodel so when it is serialized there's a pretty complicated tree of functions and data – Simon_Weaver Jul 21 '14 at 19:34
  • I must admit, I was frustrated that they'd "fixed" this then backtracked on it, but it is what it is at the moment! – Paul Manzotti Jul 22 '14 at 10:53
0

Looks like it was a false alarm.

While toJS does indeed retain the function references it was not Knockout itself that is invoking them.

I passed my data directly to jQuery's ajax function to make a POST request, and it was jQuery's JSON serialization which was actually causing the invocation..

If I passed ko.toJSON(obj) or even JSON.stringify(ko.toJS(obj)) to jQuery then it worked fine.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689