Search code examples
knockout.jsknockout-mvc

Unable to process binding error knockout


If my code appears a lot to you then just see commented code and you will understand the error. My HTML code is:

<div data-bind="foreach: showAds">
        Title: <span data-bind="text: title"></span>
        description: <span data-bind="text: description"></span>
        postedby:<span data-bind="text: postedByName"></span>
        <div data-bind="foreach: showMobileAd">
            color: <span data-bind="text: color"></span>
            price: <span data-bind="text: price"></span>
            <span data-bind="html:isNegotiable"></span>
            condition: <span data-bind="text: isNew"></span>
        </div>

        <div data-bind="foreach:showComment">
            @*<textarea id="commentDescription" data-bind="value:newComment"></textarea>
            <input type="button" data-url="/api/comment" data-bind="click: addcomment" value="submit" />*@
            postedBy:<span data-bind="text: postedByName"></span><br />
            <span data-bind="text: description"></span><br />
            <span data-bind="text: time"></span><br />
            <div data-bind="foreach: showCommentReply">
                postedBy (reply):<span data-bind="text: postedByName"></span><br />
                <span data-bind="text: description"></span><br />
                <span data-bind="text: time"></span><br />
            </div>
        </div>
    </div>

My js code is:

function mobilead(data) {
    var self = this;
    data = data || {};
    self.color = data.color;
    self.price = data.price;
    if (data.isNew) {
        self.isNew = 'New';
    } else {
        self.isNew = 'Used'
    }
    if (data.isNegotiable) {
        self.isNegotiable = 'Negotiable';
    } else {
        self.isNegotiable= '<strike>Negotiable</strike>'
    }
}
function commentReply(data) {
    var self = this;
    data = data || {};
    self.description = data.description;
    self.postedByName = data.postedByName;
    self.postedById = data.postedById;
    self.time = data.time;
}
function comment(data) {
    var self = this;
    data = data || {};
    self.description = data.description;
    self.postedByName = data.postedByName;
    self.postedById = data.postedById;
    self.time = data.time;
    self.showCommentReply = ko.observableArray();
    if (data.commentReply) {
        var reply = $.map(data.commentReply, function (item) { return new commentReply(item); });
       //self.showcommentReply(reply);
    }
    self.newComment = ko.observable();
    self.addComment = function () {
        var com = new comment();
        com.adId = self.adId;
        com.description(self.newComment());
        return $.ajax({
            url: 'api/Comment',
            dataType: "json",
            contentType: "application/json",
            cache: false,
            type: 'POST',
            data: ko.toJSON(com)
        })
        .done(function (res) {
            self.showComment.splice(0, 0, new comment(res));
            self.newComment('');
        })
        .fail(function () {
            toastr.info("failed to post comment", "info");
        })
    }
}

function ad(data) {
    var self = this;
    data = data || {};
    self.title = data.title;
    self.description = data.description;
    self.postedByName = data.postedByName;
    self.showMobileAd = ko.observableArray();
    self.showComment = ko.observableArray();
    if (data.mobilead) {
        var mobad = $.map(data.mobilead, function (item) { return new mobilead(item); });
        self.showMobileAd(mobad);
    }
    if (data.comment) {
        var cmt = $.map(data.comment, function (item) { return new comment(item); });
        self.showComment(cmt); 
    }

}

function viewModel() {
    var self = this;
   self.showAds = ko.observableArray();
    self.loadad = function () {
        var adId = $("#adId").val();
        url_address = '/api/Electronic/' + adId;
        $.ajax({
            url: url_address,
            dataType: "json",
            type: 'GET'
        })
        .done(function (data) {
            var mappedads = $.map(data, function (item) { return new ad(item); });
            self.showAds(mappedads);
        })
        .fail(function () {
            Error("error");
        });
    }

    self.loadad();
    return self;
} ko.applyBindings(new viewModel());

The error is on three commented lines.(of course it shows error only when I uncomment these lines)

  1. In comment function error is self.showcommentReply is not a function.
  2. On two commented lines in HTML code error is Uncaught ReferenceError: Unable to process binding "foreach: function (){return showComment }" Message: Unable to process binding "click: function (){return addcomment }" Message: addcomment is not defined

Whats wrong with my code? How can I tackle with these two errors?


Solution

  • Always use () convention if you want to see view & viewModel in sync and changes to reflect either way

    Try modifying

    self.showAds=mappedads

    to

    self.showAds(mappedads)