Search code examples
javascripthtmlknockout.jsmappingko.observablearray

Knockout Observable Array Length always 0


When calling the length of any observable in the customerOverview view model I receive a length of zero. There is data present in the observables as the bindings update with data, however the length remains at 0. The base view model, 'CustomerCentral', returns lengths properly. I need the length of some observables in 'CustomerOverview' to do some conditional statements.

HTML Bindings

<ul class="nav nav-list">
      <li class="nav-header">Contacts</li>
      <!--ko  if: customerOverview.contacts().length == 0-->
      <li>No contacts associated with this customer</li>
       <!-- /ko -->
      <!--ko  foreach: customerOverview.contacts()-->
      <li>
      <a data-bind="click: $root.customerOverview.viewContact"><i class="icon-chevron-                        right single pull-right">
       </i><span data-bind="text: FirstName"></span><span data-bind="text: LastName"></span>
      </a></li>
      <!-- /ko -->
</ul>

JS

function CustomerOverview() {
        var self = this;        

        self.contacts = ko.observableArray([]);           

        self.getCustomerContacts = function () {
            requestController = "/CRM/CustomerCentral/CustomerContacts";
            queryString = "?id=" + self.customer().Id();
            $.ajax({
                cache: false,
                type: "GET",
                dataType: "json",
                url: baseURL + requestController + queryString,
                headers: { "AuthToken": cookie },
                success:
                        function (data) {
                            if (data.data.length > 0) {

                                self.contacts(ko.mapping.fromJS(data.data));

                                console.log(self.contacts().length);
                            }
                        }
            });
        };
};
   function CustomerCentral() {

        var self = this;

        self.customerOverview = ko.observable(new customerOverview());
};

var vm = new CustomerCentral();
    ko.applyBindings(vm);

Console cmd: vm.customerOverview().contacts().length 0

---------------------------SOLUTION ---------------------- observableArray.push()

The issue turned out to be this line :

  self.contacts(ko.mapping.fromJS(data.data));

SOLUTION: Adding .push() to this enabled the length property of the array to be incremented. I had assumed ko.mapping would handle this but it does not. Changing the variable to observable had no effect.

 $.each(data.data, function () {
          self.contacts.push(ko.mapping.fromJS(this));
           console.log(self.contacts().length);
                                    });

Solution

  • observableArray.push()

    The issue turned out to be this line :

    self.contacts(ko.mapping.fromJS(data.data));
    

    SOLUTION: Adding .push() to this enabled the length property of the array to be incremented. I had assumed ko.mapping would handle this but it does not. Changing the variable to observable had no effect.

    $.each(data.data, function () {
              self.contacts.push(ko.mapping.fromJS(this));
               console.log(self.contacts().length);
                                        });