javascriptknockout.jsdurandal

Knockout foreach binding not working


I'm following John Papa's jumpstart course about SPA's and trying to display a list of customers loaded via ASP.NET Web API the knockout foreach binding is not working. The Web API is working fine, I've tested it on it's own and it is returning the correct JSON, because of that I won't post the code for it. The get method simply returns one array of objects, each with properties Name and Email. Although not a good practice, knockout is exposed globaly as ko by loading it before durandal.

I've coded the customers.js view model as follows

define(['services/dataservice'], function(ds) {
     var initialized = false;

     var customers = ko.observableArray();

     var refresh = function() {
         return dataservice.getCustomers(customers);
     };

     var activate = function() {
          if (initialized) return;
          initialized = true;
          return refresh();
     };

     var customersVM = {
          customers: customers,
          activate: activate,
          refresh: refresh
     };

     return customersVM;
});

The dataservice module I've coded as follows (I've not wrote bellow the function queryFailed because I know it's not being used)

 define(['../model'], function (model) {
     var getCustomers = function (customersObservable) {
          customersObservable([]);

          var options = {url: '/api/customers', type: 'GET', dataType: 'json'};

          return $.ajax(options).then(querySucceeded).fail(queryFailed);

          function querySucceeded(data) {
               var customers = [];

               data.forEach(function (item) {
                   var c = new model.Customer(item);
                   customers.push(c);
               });

               customersObservable(customers);
          }
     };

     return {
          getCustomers: getCustomers
     };
 });

Finaly the model module was built as follows:

define(function () {

    var Customer = function (dto) {
        return mapToObservable(dto);
    };

    var model = {
        Customer: Customer
    };

    return model;

    function mapToObservable(dto) {
        var mapped = {};
        for (prop in dto)
        {
            if (dto.hasOwnProperty(prop))
            {
                mapped[prop] = ko.observable(dto[prop]);
            }
        }

        return mapped;
    }
});

The view is then simply a list, it is simply:

<ul data-bind="foreach: customers">
    <li data-bind="text: Name"></li>
</ul>

But this doesn't work. Any other binding works, and I've looked on the console window, and it seems the observable array is being filled correctly. The only problem is that this piece of code doesn't show anything on screen. I've reviewed many times the files but I can't seem to find the problem. What's wrong with this?


Solution

  • You can use the knockout.js context debugger chrome extension to help you debug your issue

    https://chrome.google.com/webstore/detail/knockoutjs-context-debugg/oddcpmchholgcjgjdnfjmildmlielhof