I want to display the detail of my user data within a Bootstrap modal. I load the data with AJAX, and bind them to a Knockout ViewModel with the knockout mapping plugin.
Data is properly loaded and bound to knockout model, but I never see the data on UI. Does anybody see where the problem is?
user.js
var model = new UserViewModel();
$(document).ready(function() {
ko.applyBindings(model);
});
userViewModel.js
function UserViewModel() {
var self = this;
self.userHelper = ko.observable();
self.userHelper.user = ko.observable();
self.loadUserData = function(userId) {
$.ajax({
type : "POST",
url : "/user/loadUserDetail.htm",
data: {"userId": userId},
success : function(response) {
var parsedJSON = $.parseJSON(response);
var userHelper = new UserHelper(parsedJSON);
self.userHelper = userHelper;
// correct first name is printed
console.log(userHelper.user.firstName());
$("#user-dialog").modal('show');
},
error : function(e) {
showErrorBox('Error: ' + e.status);
}
});
}
}
function UserHelper(data) {
this.user = ko.mapping.fromJS(data.user);
this.availableGroups = ko.mapping.fromJS(data.availableGroups);
this.errors = ko.observableArray(mapDictionaryToArray(data.errors));
}
user.jsp
<input type="text" class="form-control input-sm" data-bind='attr:{value: userHelper.user.firstName}' name="user.firstName" />
Update:
I updated my code, but the data is still not diplayed on the UI. Any errors here?
userViewModel.js
var userHelper = {
user: ko.observable(),
availableGroups: ko.observableArray([]),
errors: ko.observableArray([])
};
function mapData(data) {
userHelper.user = ko.mapping.fromJS(data.user);
userHelper.availableGroups = ko.mapping.fromJS(data.availableGroups);
userHelper.errors = ko.observableArray(mapDictionaryToArray(data.errors));
}
function UserViewModel() {
var self = this;
self.loadUserData = function(userId) {
$.ajax({
type : "POST",
url : "/user/loadUserDetail.htm",
data: {"userId": userId},
success : function(response) {
var parsedJSON = $.parseJSON(response);
mapData(parsedJSON);
console.log(userHelper.user.firstName());
registerClickListener();
$("#user-dialog").modal('show');
},
error : function(e) {
showErrorBox('Error: ' + e.status);
}
});
}
}
JSP:
<input type="text" class="form-control input-sm" data-bind='attr:{value: userHelper.user.familyName}' name="user.familyName" />
You misuse the ko's observable:
self.userHelper = ko.observable();
//...
self.userHelper = userHelper; // This is wrong
//...
self.userHelper(userHelper); //This is correct
You will also have to change usage:
.. data-bind='attr:{value: userHelper().user.firstName}'...
Also, since your initial userHelper
value is undefined, knockout will have problems binding it first time, you have to add checks into HTML if userHelper() is define.
Another way is you can initially define an empty model of UserHelper, and then just load new JSON values into it when ajax complete