0
votes

I have a viewModel that looks something like this when simplified:

var viewModel = function(){
  var self = this;
  self.selectedObject = ko.observable({});
  self.getUnit = function(){
    //get the selected object from the server side as json
    self.selectedObject(ko.mapping.fromJS(data,mapping));
  };
  self.addObjectMember = function(){
    self.selectedObject().objectMembers.push(new ObjectMemberViewModel(null, self.selectedObject()));
  self.save = function(){
    var data = ko.mapping.toJS(self.selectedObject);
    //ship data to server
  }

The data received from the server contains an array called objectMembers that has some properties inside it. The properties might differ between different objects.

My mapping object look like this:

var mapping = {
  'objectMembers': {
    create: function(options){
      return new ObjectMemberViewModel(options.data, options.parent);
    }
  }
};

To see my problem, I'll give an example:

The user loads the page, and then fetches an object. That object includes two elements inside the objectMembers array. Then those are mapped using the ko.mapping.fromJS and everything works just fine. I can modify my viewModel using my model and the viewModel is updated. Then the user clicks a button that triggers the addObjectMember function, adding a third entry to the observableArray. I can interact with this also, and any changes done to my model can be seen in the viewModel as expected.

The problem comes when I click save. If I debug the save method, and check the contents of self.selectedObject, I can see that it contains what I want it to, but the object that is mapped back into the variable data has the last element in the objectsMembers array as an empty object ({}). The two other object look as I want them to.

I think I know why. The two first object have their __ko_mapping__.mappedProperties containing all the properties they had when it got mapped initially. The last one however has an empty __ko_mapping__.mappedProperties, and therefore I guess that no properties are mapped back.

So I need to do one of these things I guess:

  1. When adding the object to the array on addObjectMember I need to get the __ko_mapping__.mappedProperties set so that it gets mapped back when I save.
  2. When mapping back, I include all the properties on the mapped object regardless of their presence inside the __ko_mapping__.mappedProperties.

I have no clue how to do any of them that does not feel like a dirty hack, so any help here would be appreciated.

1
It seems that the ko.toJS will not care about what was mapped originally. Are there any problems combining it so that I use ko.mapping.fromJS to create the model, and then ko.toJS to make it back into javascript?Øyvind Bråthen

1 Answers

1
votes

I ended up using ko.toJS instead of ko.mapping.toJS. ko.toJS does not care about __ko_mapping__, and maps everything (including __ko_mapping__).

That means it maps a bit more than I need, but other than that it works just fine.