Knockout Observed array length is always 0

When I call the length of any observable customerOverview view in the model, I get zero. There is data in the observed data, like updating data bindings, however the length remains equal to 0. The CustomerCentral base view model returns the lengths properly. I need the length of some observables in "CustomerOverview" to execute 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); 

Cmd console: vm.customerOverview (). contacts (). length 0

--------------------------- DECISION ------------------- --- observableArray.push ()

The problem turned out to be this:

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

SOLUTION: Adding .push () to this allowed us to increase the value of the length property of the array. I assumed that ko.mapping will handle this, but it is not. The change in the variable did not affect the observed.

  $.each(data.data, function () { self.contacts.push(ko.mapping.fromJS(this)); console.log(self.contacts().length); }); 
+8
javascript html mapping ko.observablearray
source share
5 answers

observableArray.push ()

The problem turned out to be this:

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

SOLUTION: adding .push () allows you to activate the length property of the array. I assumed that ko.mapping will handle this, but it is not. Changing the variable to the observed had no effect.

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

I think your problem is not that you have customerOverview property as observable

to try:

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

or

  self.customerOverview = ko.computed(function(){ return new CustomerOverview(); }); 

Working example:

http://jsfiddle.net/dvdrom000/RHhmY/1/

HTML

 <span data-bind="text: customerOverview().contacts().length"></span> <button data-bind="click: customerOverview().getCustomerContacts">Get contacts</button> 

Js

 function CustomerOverview() { var self = this; self.contacts = ko.observableArray([]); self.getCustomerContacts = function () { self.contacts.push(1); self.contacts.push(2); self.contacts.push(3); }; }; function CustomerCentral() { var self = this; // Is this a correct way. Am I breaking something with this? self.customerOverview = ko.observable(new CustomerOverview()); }; var vm = new CustomerCentral(); ko.applyBindings(vm); 
+6
source share

Knockout provides a set of manipulation functions for arrays that mirror the functions found in JavaScript; pop, push, shift, unshift, reverse, sort and splice. Along with the operations you expect, these array functions will also automatically notify observers that the array has changed. JavaScript methods will not. If you want your user interface to be updated when the count is changed, you want to be careful to use the Knockout functions.

Link: http://ryanrahlf.com/knockout-js-observablearray-not-updating-the-ui-heres-how-to-fix-it/

So basically, to solve your problem, you just need to use the push knockout function directly on the observed array instead of using the javascript push method. Consequently:

Change this:

 self.contacts( ).push( data.data ); 

Thus:

 self.contacts.push( data.data ); 

And you can use the contacts (). Length property in your html and receive notifications of every change in the array.

+2
source share

I had such problems, and IIRC, this is because I used double equalities (==) instead of triple equal (===) in comment conditionals. Take a picture.

0
source share

Instead:

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

You must have:

 self.contacts(ko.mapping.fromJS(data.data)**()**); 
0
source share

All Articles