Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout computed array not updating

Tags:

knockout.js

I am facing an issue that the computed observable array is not updated when a new item is added.

self.FilteredCityList = ko.computed(function() {
  var filteredCollection = ko.utils.arrayFilter(self.CityListCollection(), function(r) {
    var matchingItem = ko.utils.arrayFilter(self.LocationCollection(), function(r1) {
      return r1.LocationCode() == r.LocationCode();
    });
    if (matchingItem.length > 0) {
     return false;
    }
    return true;
  });
  return filteredCollection;
}, this);

When I add an item in self.LocationCollection() the computed array is not updated.

like image 359
Venkat Avatar asked Dec 26 '22 13:12

Venkat


1 Answers

You've mentioned in your comment that you've used the following code to add items to your LocationCollection which caused your problem:

self.LocationCollection().push(item);

Where

self.LocationCollection = ko.observableArray();

To enable knockout's change tracking you need to call push on the observableArray directly (e.g. without the parenthesis ()) as described in the documentation:

self.LocationCollection.push(item);

But what is the difference?

The ko.observableArray() call will return a function. To get the underlying array you need to call this function (e.g self.LocationCollection()) which returns the stored array.

At this point when you call LocationCollection().push(item) you will call push on the underlying array so knockout won't know about it and it doesn't trigger your computed observable.

That's why in knockout they defined their own push method on the observableArray itself what you need to call with the syntax LocationCollection.push(item) and because it's knockout's method it will correctly track the changes.

Sample fiddle.

like image 74
nemesv Avatar answered Jan 17 '23 15:01

nemesv