Based on the KnockoutJS mapping documentation what I am trying to do seems really straightforward, however I am not getting the results I expect.
So for some simple test html-
<div data-bind="with: rootItem">
<p data-bind="text: subProperty"></p>
<div data-bind="with: subObject">
<p data-bind="text: subSubProperty"></p>
</div>
and this simple view model and application
var vm = function(){
this.rootItem = ko.observable();
this.loadData = function(data){
//map the rootObject here
ko.mapping.fromJS(data,{},this.rootItem());
//this.rootItem is undefined
console.log(this.rootItem());
};
};
//create new viewmodel
var myVM = new vm();
//create some dummy data with nested objects and properties
var data = {
subProperty: "Top Level Property",
subObject: {
subSubProperty:"Sub Level Property",
},
};
//load the data
myVM.loadData(data);
//apply the vm
ko.applyBindings(myVM);
So the vm.rootObject never gets set. Am I missing something about the ko.mapping plugin behavior?
This implementation of the loadData function gets the desired result, but adds the extra step.
this.loadData = function(data){
//map the rootObject here
this.rootItem(ko.mapping.fromJS(data));
//this.rootItem is an object with a nested object and observable properties
console.log(this.rootItem());
};
Why does the first method fail? In the documentation it states pretty clearly that “The third parameter to ko.mapping.fromJS indicates the target.”
Here is a fiddle demonstrating what is happening.
The documentation is right “The third parameter to ko.mapping.fromJS indicates the target.”.
But you provide the wrong target:
because when you call
ko.mapping.fromJS(data,{}, this.rootItem());thethis.rootItemis initialized withundefinedso the mapping plugin cannot use it a target.Use an empty object when creating the
rootItemand it will work fine:Demo JSFiddle.