3

I am in the process of learning about knockout/json/mvc et al and have tried to put together an example project, but for some reason I am unable to get the data to bind correctly.

In the code snippet below, I get some JSON data from a web server and then try to map it to a function and then eventually to my knockout observableArray. What I then do is use this observableArray to bind to a HTML table. However the HTML table is not displaying any data. I put a label on to the HTML page and this does print out but with a toString() value of : [Object object] five times, which matches the amount of properties in the JSON data.

Can anyone see anything obvious I am missing?

JSON received from web server:

{ "Id": 1, "Name": "Inst123", "Price": 10, "DateTime": "2014-01-16T17:22:43.6383507+00:00", "Description": "Descriptions" };

.

ViewModel

$(document).ready(function () {
    var gtViewModel = new GvTradeViewModel();
    ko.applyBindings(gtViewModel);
    console.log("ViewModel created");
});

    var GvTradeViewModel = function () {
    var self = this;
    self.gvTrades = ko.observableArray([]);

    var apiUrl = "http://localhost:57858/api/Trade/1";

    console.log("Starting JSON data retrieval from: " + apiUrl);

    $.getJSON(apiUrl)
       // Handle success event.
      .done(function (jsonData) {
          if (jsonData.isEmptyObject)
              console.log("NoData recieved");
          else {
              console.log("JSON data: " + jsonData);

              var mappedTrades = $.map(jsonData, function (gvTradeData) {
                  return new GvTrade(gvTradeData);
              });
              self.gvTrades(mappedTrades);
              console.log(self.gvTrades);

          }
      })
      // Handle error/fail event.
     .fail(function (jqxhr, textStatus, error) {
         var err = textStatus + ", " + error;
         console.log("Request Failed: " + err);
     });
};

function GvTrade(data) {
    this.TradeId = ko.observable(data.TradeId);
    this.InstrumentName = ko.observable(data.InstrumentName);
    this.DateTime = ko.observable(data.DateTime);
    this.Price = ko.observable(data.Price);
    this.Description = ko.observable(data.Description);
}

HTML

<table>
<thead>
    <tr>
        <th>TradeId</th>
        <th>InstrumentName</th>
        <th>Price</th>
        <th>DateTime</th>
        <th>Description</th>
    </tr>
</thead>
<tbody data-bind="foreach: $data.gvTrades">
    <tr>
        <td data-bind="text: InstrumentName"></td>
        <td data-bind="text: Price"></td>
        <td data-bind="text: DateTime"></td>
        <td data-bind="text: Description"></td>
    </tr>
</tbody>

1
  • 1
    Not sure why you have $data there. Just foreach: gvTrades should work. Commented Jan 16, 2014 at 18:14

1 Answer 1

1

The JSON coming from your server represents a single object and not an array.

So when you are calling $.map then it does not correctly maps your data as an array, so you will end up some unusable objects.

To fix this you need to make sure that your jsonData containing an array before the map operation, you can do this with calling jQuery.makeArray on it (or you can have an if which is based on your data type decide whether you need to map or not):

var mappedTrades = $.map($.makeArray(jsonData), function (gvTradeData) {
    return new GvTrade(gvTradeData);
});

Demo JSFiddle.

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

Comments

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.