0

I'm trying to control what data should be serialized before sending it back to my server. To do this :

viewModel.prototype.toJSON = function () {
  var copy = ko.toJS(this);
  delete copy.QuoteListViewModel;
  return copy;
};

But prototype is undefined and it fails.

viewModel is created by mvcKnockout and does exist because I can do things like:

viewModel.QuoteSelectedViewModel = ko.observable();

So why is prototype undefined ?

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
Sam
  • 13,934
  • 26
  • 108
  • 194
  • 2
    What is viewmodel? Is it just a JS object, or is it a function? Prototype applies to functions only, I believe, not straight-up JS objects. – Paul Manzotti Mar 15 '13 at 13:26
  • Is the constructor declared before you try to add to the prototype? – Wryte Mar 15 '13 at 13:26
  • @Paul hum, actually you are right, viewModel is defined as : var viewModel = ko.mapping.fromJS(viewModelJs); How would I delete a property before submitting to server then ? – Sam Mar 15 '13 at 13:31

2 Answers2

1

Prototype applies to functions only, I believe, not straight-up JS objects, so I'm going to guess that your view model isn't declared as a function.

To answer the question in your comment, to delete a property before sending to the server, have a look at the section in the mapping plugin documentation on mapping using an ignore map, which will, rather unsurprisingly, ignore the properties you tell it to when copying a view model over to a JS object.

Ian
  • 50,146
  • 13
  • 101
  • 111
Paul Manzotti
  • 5,107
  • 21
  • 27
  • I can see that I can ignore properties when calling ko.fromJS, but it does not seem possible to do it the other way around, that is, when calling ko.toJS. At least the documentation is not clear about that. Are you sure I can ignore properties when mapping back to JS object ? – Sam Mar 15 '13 at 13:42
  • Since when doesn't `.prototype` apply to every type? Or is this something special with Knockout that you're referring to? – Ian Mar 15 '13 at 13:47
  • @user1098555 You need to use the mapping plugin, as I mentioned, not the ko.toJS method. – Paul Manzotti Mar 15 '13 at 13:51
  • @Ian I'm only going on the error message he reported. I assume that it applies to everything in JS, but looking at this http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work it doesn't. Not sure I deserve a vote down for that. – Paul Manzotti Mar 15 '13 at 13:54
  • @PaulManzotti I don't see anything in that post that suggests `.prototype` isn't defined at times... – Ian Mar 15 '13 at 14:03
  • @Ian Other than the sentence "But prototype is undefined and it fails."? – Paul Manzotti Mar 15 '13 at 14:06
  • @PaulManzotti In the SO link you just posted – Ian Mar 15 '13 at 14:07
  • @Ian Christoph's first comment on his accepted answer: "yes, it's wrong - only function objects have a predefined prototype property, so your code will throw an error, eg 'obj.prototype is undefined' in FF" – Paul Manzotti Mar 15 '13 at 14:09
  • @PaulManzotti I think I was confusing the terminology (and forgot that function instances have a prototype specifically). I was thinking of setting the prototype for `Function`, `Object`, `String`, etc., where's it applicable to all types. But when it comes to instances, only functions have a prototype, so you're right. Sorry about that, I'll edit your post so I am able to change my vote – Ian Mar 15 '13 at 14:16
  • @Ian Don't worry, I had to go double check it myself, as I wasn't convinced either! :) – Paul Manzotti Mar 15 '13 at 14:19
0

Why would you copy the object and delete the property, while you can ignore it during the mapping? Here's a simple example:

function viewmodel() {
    var self = this;

    this.ignore = ko.observable("ignore");
    this.copy = ko.observable("copy");

    this.toJS = function () {
        var mapping = {
            'ignore': ["ignore", "toJS"]
        }

        return ko.mapping.toJS(self, mapping);
    };
};

var vm = new viewmodel();
ko.applyBindings(vm);

console.log(vm.toJS());

JSFiddle.

MarcoK
  • 6,090
  • 2
  • 28
  • 40