2

Only starting with knockout.js, but already running into some trouble when trying to make a computed method based on 2 different observableArrays

Using the documentation on knockout.js' website, I've created the following viewmodel:

var Cart = function() {
  var self = this;

  self.Products = ko.observableArray([]);
  self.Products2 = ko.observableArray([]);
  self.Messages = ko.observableArray([]);

  self.TotalAmount = ko.computed(function() {
    var result = 0;
    ko.utils.arrayForEach(
      this.Products().concat(this.Products2()),
      function(item) {
        result+=item.AmountIncludingVAT();
      }
    );
    return result;
  });
};

Doing this throws an error of "Uncaught TypeError: Object #<error> has no method 'concat'.

I know there is this function called arrayPushAll, but it's a destructive function which would alter the original observableArray. (I don't think this is something I want).

Is there any clean way to achieve what I'm trying to do? Or do I have to make 2 different calls to arrayForEach, one for each array?

Kippie
  • 3,760
  • 3
  • 23
  • 38
  • Something else is wrong with your code. Altough the `observableArray` does not have a `concat` method but array does. And with `this.Products()` you are unwrapping the observable and working on the array. So please create a working JSFIddle which shows this error! – nemesv Oct 07 '13 at 09:31
  • Apart from the accepted answer, the concat function does **NOT** alter the existing array, it returns a new array after performing concatenation. You are discarding the return value which actually contains the merged arrays _MDN link_: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat – Jay Jodiwal May 17 '19 at 17:47

2 Answers2

6

Change:

this.Products().concat(this.Products2()),

to:

self.Products().concat(self.Products2()),

Inside your TotalAmount ko.computed function.

this in the context of your computed refers to the global object rather than the view model. So you need to use the self variable that is assigned the correct this value earlier.

Working Example - http://jsfiddle.net/55kZp/

Richard Dalton
  • 35,513
  • 6
  • 73
  • 91
6

concat didn't works for me .. I did push

self.Products.push.apply( 
  self.Products, self.Products2()
);
rab
  • 4,134
  • 1
  • 29
  • 42