I'm having some problems figuring out why this simple Knockout mapping isn't working. I'm not sure if the returned JSON is invalid or if my mappings are wrong or if it's simply the bindings.
The data structure is a parent Conversation object with an array of Message objects.
On the bindings I'm using foreach: Conversation at the moment because I have this working if I wrap the whole thing a single element array.
My bindings
<div data-bind="foreach: conversation">
<div data-bind="foreach: messages">
<div class="well">
<div data-bind="text: sender_name"></div>
<div data-bind="text: subject"></div>
<div data-bind="text: body"></div>
<div data-bind="text: updated_at"></div>
</div>
</div>
</div>
My ViewModel, faked JSON and mappings
// Sample JSON to return for initialization; 2 second delay
var conversationData = {
json: $.toJSON(
{"id":8,"subject":"Hello JB! Email two!",
"updated_at":"Sep 27",
"originator":"James Pablo",
"count_messages":"(2)",
"messages":[{"subject":"RE: Hello JB! Email two!",
"body":"Thanks for the message!",
"sender_name":"Joe Flynn","updated_at":"Sep 27"},
{"subject":"Hello JB! Email two!",
"body":"Body text",
"sender_name":"James Pablo",
"updated_at":"Sep 27"}
]
}
),
delay: 1
}
function Conversation(data) {
ko.mapping.fromJS(data, {}, this);
}
function Message(data) {
ko.mapping.fromJS(data, {}, this);
}
var map = {
create: function(options) {
return new Conversation(options.data);
},
messages: function(options) {
return new Message(options.data);
}
}
var ViewModel = function() {
var self = this;
self.conversation = ko.observable();
// Use JSFiddle echo to simulate an AJAX service
(function() {
$.ajax({ url:"/echo/json/", data:conversationData, type:"POST",
success:function(data)
{
// Map the returned JSON to the View Model
ko.mapping.fromJS(data, map, self.conversation);
}
});
})();
console.log(self.conversation());
};
ko.applyBindings(new ViewModel());
This JSFiddle works when I'm returning the JSON data wrapped in a single element array.
If I remove the array wrapper from the JSON in this JSFiddle (which is what I want as I only want to render a single conversation) then I can't get it to work. Any ideas?
Create function only works on arrays.
Try this
Removed Convension from map literal and did
self.conversation(new Conversation(data));