Valermus Valermus - 5 months ago 17
jQuery Question

Uncaught ReferenceError: Unable to process binding with Ajax

I have two layered MVC4 .NET Application with DAL and Web layers.
I am having problems when trying to bind data with Ajax returned data.

On Html, i am trying to get SubcriteriaList members and create the table for each member while filling their values.

HTML:

<h2 style="text-align:center">Criteria Info</h2>
<table align="center">
<tr>
<th colspan="3">Subcriteria Info</th>
</tr>
<tr>
<td>
<table class="table-condensed">
<tbody data-bind="foreach:SubcriteriaList">
<tr>
<td>
<table class="table-condensed">
<tr>
<th colspan="5" width="100%;">
<select style="width:100%;"></select>
</th>
<td>
<a class="btn btn-small btn-danger" href="#" style="margin-bottom:10px">X</a>
</td>
</tr>
<tr>
<td>
<label style="padding-top:5px;">Code</label>
</td>
<td>
<input class="input-large" placeholder="Code" data-bind="value:Code" />
</td>
<td>
<label style="padding-top:5px;">Weight</label>
</td>
<td>
<input class="input-large" placeholder="Weight" data-bind="value:Weight" />
</td>
</tr>
<tr>
<td>
<label style="padding-top:5px;">Name</label>
</td>
<th colspan="4" width="100%;">
<input style="width:100%;" class="input-large" placeholder="Name" data-bind="value:Name" />
</th>
</tr>
<tr>
<td>
<label style="padding-top:5px;">Goal</label>
</td>
<td>
<input class="input-large" placeholder="Goal" data-bind="value:Goal" />
</td>
<td>
<label style="padding-top:5px;">Achieved</label>
</td>
<td>
<input class="input-large" placeholder="Achieved" data-bind="value:Achieved" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr style="text-align:right">
<td>
<p>
<button class="btn btn-small btn-primary">Add Criteria</button>
</p>
</td>
</tr>
</table>


Knockout JS ViewModel in different JavaScript file.

JavaScript File:

function SubCriteriaViewModel() {
var self = this;

self.id = ko.observable("");
self.code = ko.observable("");
self.name = ko.observable("");
self.weight = ko.observable("");
self.goal = ko.observable("");
self.achieved = ko.observable("");
self.isActive = ko.observable("");

var Subcriteria = {
Id: self.id,
Code: self.code,
Name: self.name,
Weight: self.weight,
Goal: self.goal,
Achieved: self.achieved,
IsActive: self.isActive
};

self.Subcriteria = ko.observable();
self.SubcriteriaList = ko.observableArray();

// Initializing the view-model
$.ajax({
url: "/Subcriteria/GetAllSubcriteria",
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
alert(data);
//Probably Problem is here
self.SubcriteriaList(data); //Putting the response in ObservableArray
alert(SubcriteriaList);
alert(Subcriteria);
}
});
}
var viewModel = new SubCriteriaViewModel();
ko.applyBindings(viewModel);


When
alert(data)
hits i can see;
[object Object],[object Object],[object Object]

return succesfuly however i can not add this JsonResult to SubCriteriaList array.

Thus (i think) i am getting

*Uncaught ReferenceError: Unable to process binding "value: function(){return Code }" Message: Code is not defined*


error.

How can i fill this SubcriteriaList array with this Ajax usage?

Thanks in advance.

Answer

Your data binding is Code, but your observable is code. Variable names are case sensitive. You'll need to fix all of them that do not match, as once you fix this one, the others will fail.

You've got some other issues though. You're not actually mapping the response to your view model. You should probably have a parent and child viewModel. The child would have the properties, and would be the map for the ajax response. The child would maintain the list, do the ajax request, etc.

function SubCriteriaViewModel(data) {
    var self = this;

    self.id = ko.observable(data.id);
    self.code = ko.observable(data.code);
    self.name = ko.observable(data.name);
    self.weight = ko.observable(data.weight);
    self.goal = ko.observable(data.goal);
    self.achieved = ko.observable(data.achieved);
    self.isActive = ko.observable(data.isActive);        
}

function ViewModel() {
    var self = this;
    self.SubcriteriaList = ko.observableArray();

    // Initializing the view-model
    $.ajax({
        url: "/Subcriteria/GetAllSubcriteria",
        cache: false,
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        data: {},
        success: function (data) {
            var subcriteriaList = data.map(function (item) { return new SubCriteriaViewModel(item); });
            self.SubcriteriaList(subcriteriaList); //Putting the response in ObservableArray
        }
    });
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);

Then, remember to fix all of the casing issues. Here's just one:

<input class="input-large" placeholder="Code" data-bind="value:Code" />

should be

<input class="input-large" placeholder="Code" data-bind="value:code" />