Reputation: 25
I have a simple use case. I need to call a WS asynchronously and show the returned JSON on the UI. The JSON that I get back is an object with multiple properties. For simplicity, the code below only has one property. Since I have multiple properties, I am using ko.mapping.fromJS to map the JSON to the object properties. It all seems to work, except the fetched data doesn't update on the UI. If I manually update the observable, it works. But not when using ko.mapping.fromJS.
Javascript
function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");
$.ajax({
dataType: 'json',
async: true,
type: 'POST',
url: '/echo/json/',
data: {
json: '{"firstName":"Bob1"}'
}
}).done(function(data) {
console.log(data);
//self.firstName(data.firstName);//This works
self = ko.mapping.fromJS(data); //This doesn't
console.log(self.firstName());
}).fail(function(jqxhr, textStatus, error) {
alert('there was an error');
});
}
// Activates knockout.js
var avm = new AppViewModel();
ko.applyBindings(avm);
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
You can run the jsfiddle. You will see that this line works
self.firstName(data.firstName);//This works
and this line doesn't work
self = ko.mapping.fromJS(data); //This doesn't
http://jsfiddle.net/texag93/fakdf5Lw/53/
Upvotes: 1
Views: 1455
Reputation: 311865
Two things: 1) You need to create your initial view model with ko.mapping.fromJS
, and 2) you need to pass your existing view model as a second parameter to fromJS
when updating it.
So something like this instead:
// Activates knockout.js
var avm = ko.mapping.fromJS({firstName: 'Bert'});
ko.applyBindings(avm);
$.ajax({
dataType: 'json',
async: true,
type: 'POST',
url: '/echo/json/',
data: {
json: '{"firstName":"Bob1"}'
}
}).done(function(data) {
console.log(data);
ko.mapping.fromJS(data, avm);
console.log(avm.firstName());
}).fail(function(jqxhr, textStatus, error) {
alert('there was an error');
});
Updated fiddle: http://jsfiddle.net/fakdf5Lw/56/
Upvotes: 1