Wednesday, June 5, 2024
 Popular · Latest · Hot · Upcoming
23
rated 0 times [  27] [ 4]  / answers: 1 / hits: 18759  / 12 Years ago, tue, july 3, 2012, 12:00:00

I have this code:



<ul id=chats data-bind=foreach: chats>
<li>
<div class=chat_response data-bind=visible: CommentList().length == 0>
<form data-bind=submit: $root.addComment>
<input class=comment_field placeholder=Comment… data-bind=value: NewCommentText />
</form>
</div>
<a class=read_more_messages data-bind=visible: moreChats, click: showMoreChats>Read More Messages...</a>
</li>
</ul>

function ChatListViewModel(chats) {
// Data
var self = this;

self.chats = ko.observableArray(ko.utils.arrayMap(chats, function (chat) {
return { CourseItemDescription: chat.CourseItemDescription,
CommentList: ko.observableArray(chat.CommentList),
CourseItemID: chat.CourseItemID,
UserName: chat.UserName,
ChatGroupNumber: chat.ChatGroupNumber,
ChatCount: chat.ChatCount,
NewCommentText: ko.observable()
};
}));

self.moreChats = ko.observable(true);

self.showMoreChats = function () {
var LastChatGroupNumber = self.chats()[self.chats().length - 1].ChatGroupNumber;

$.ajax({
url: $.CourseLogic.dataitem.GetMoreChatsUrl,
data: {chatGroupNumber: + ko.toJSON(LastChatGroupNumber + 1) + },
type: post,
contentType: application/json,
success: function (chats) {
var chatList = self.chats();
$.each(chats, function (index, chat) {
self.chats.push(chat);
});
}
});
}

}

ko.applyBindings(new ChatListViewModel(initialData));


But I get this error when the showMoreChats function is called:



Unable to parse bindings.
Message: TypeError: CommentList is not a function;
Bindings value: visible: CommentList().length == 0



What does it mean?


More From » knockout.js

 Answers
15

It's not that CommentList is undefined, it's just that it's not an observable (hence not a function). The reason being that in your ajax callback, you are just pushing the 'chat' objects received from your server as is. You're not creating for example a new observableArray called CommentList, but you're just putting a bare array CommentList - hence the thrown error by KO.



You would need to make the same transformation as you did when constructing self.chats in the viewmodel constructor, e.g.:



$.each(chats, function(index, chat) {
self.chats.push(
{
CourseItemDescription: chat.CourseItemDescription,
CommentList: ko.observableArray(chat.CommentList),
CourseItemID: chat.CourseItemID,
UserName: chat.UserName,
ChatGroupNumber: chat.ChatGroupNumber,
ChatCount: chat.ChatCount,
NewCommentText: ko.observable()
}
);
});


By the way, you should also take a look at the ko.mapping plugin, it can do this transformation for you.



Edit: Also, for better performance you shouldn't push each individual item into the observable array, but add them in one bulk operation, something like:



self.chats( self.chats().concat( ko.utils.arrayMap(chats, function(chat) {
return { /* ... same as before ... */ };
} ) );

[#84506] Monday, July 2, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ronaldodarioc

Total Points: 441
Total Questions: 105
Total Answers: 106

Location: Christmas Island
Member since Sun, Mar 7, 2021
3 Years ago
ronaldodarioc questions
Thu, Jan 28, 21, 00:00, 3 Years ago
Sat, Nov 21, 20, 00:00, 4 Years ago
Wed, Apr 29, 20, 00:00, 4 Years ago
Fri, Mar 6, 20, 00:00, 4 Years ago
;