0

I am trying to bind an observableArray from an ajax server read but not able to bind it to the html. The json data is returning but not sure how to parse or get it to bind. I am new to Knockout.

Code:

<html>
<head>
<title></title>
<script type='text/javascript'     src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.js"></script>
<script>

function SurnameViewModel() {
  var self = this;
  self.Surnames = ko.observableArray();
  $.ajax({
    crossDomain: true,
    type: 'POST',
    url: "http://localhost/GetSurnames/Name/CID",
    dataType: 'json',
    data: { "Name": "d", "CID": "17" }, // <==this is just a sample data
    processdata: true,
    success: function (result) {
    self.Surnames= ko.mapping.fromJS(result.data);
    alert(self.Surnames()); // <== able to see the json data

    },
    error: function (xhr, ajaxOptions, thrownError) {
        alert("Failure!");
        alert(xhr.status);
        alert(thrownError);
    }
  });
}


// Activates knockout.js
$(document).ready(function() {
  ko.applyBindings(new SurnameViewModel())
});
</script>
</head>
<body>
<h2>Surnames</h2>
<table>
    <thead><tr>
        <th>ID</th><th>Surname</th>
    </tr></thead>
        <tbody data-bind="foreach: Surnames">
        <tr>
        <td data-bind="text: Surnames().id"></td>
        <td data-bind="text: Surnames().homename"></td>

    </tr>    
</tbody>
</table>

</body>
</html>

Json Data Returned from the alert

data: "[{"id":3,"homename":"DCosta"}]"

What am doing wrong here?

Edit: Working code

This is what worked for me.

I change this

ko.mapping.fromJS(result.data, {}, self.Surnames);

to

ko.mapping.fromJSON(result.data, {}, self.Surnames);

and in the html from this

<tr>
    <td data-bind="text: Surnames().id"></td>
    <td data-bind="text: Surnames().homename"></td>

</tr>    

to this

<tr>
    <td data-bind="text: id"></td>
    <td data-bind="text: homename"></td>

</tr>    

1 Answer 1

1

You have two problems:

In your view when using the foreach binding you are "inside" of the context of the array so you don't need to write out the array name (Surnames()) again:

<tbody data-bind="foreach: Surnames">
   <tr>
       <td data-bind="text: id"></td>
       <td data-bind="text: homename"></td>
   </tr>
</tbody>   

When you are getting back the data from the server you are overriding the Surnames array, the correct way of using the mapping plugin here:

ko.mapping.fromJS(result.data, {} /* empty mapping options */, self.Surnames);

Or

self.Surnames(ko.mapping.fromJS(result.data)());

Note the () in the above code, you need this because the ko.mapping.fromJS(result.data) will return an ko.observableArray without getting its underlaying value with the () you would end up with your Surnames containing another ko.observableArray

Sign up to request clarification or add additional context in comments.

7 Comments

I tried bot methods am getting the in the console Uncaught ReferenceError: Unable to parse bindings. Bindings value: text: id Message: id is not defined In there server call I am actually passing CID have updated my question
It does not matter what do you send to the server. It matters what you get back in your success callback: so please alert what you get back from the server success: function (result) { alert(result) } and post that. You can also try fromJSON: ko.mapping.fromJSON(result.data, {} /* empty mapping options */, self.Surnames);
@Adrian Here is a working jsfiddle created with using your sample data: data: "[{"id":3,"homename":"DCosta"}]" jsfiddle.net/X7feb
I used ko.mapping.fromJSON(result.data, {}, self.Surnames); and it worked. The data that I get after adding alert(result.data) is [{"id":3,"homename":"D\u0027Costa"}]
do I need to add JSON.stringify as in your jsfiddle example? Without that it worked
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.