2

I am trying to implement a simple 'toString' function for an observableArray.

When using this code which seems the most appropriate to me

var viewModel = {

  name: ko.observable('test'),
  arr: ko.observableArray(['item1']),

  third: ko.computed(function(){

    return this.arr().join();
  })
};

ko.applyBindings(viewModel);

I get a this.arr is not a function error

Why is this happening?

If I run it like this everything is ok.

var viewModel = {

  name: ko.observable('test'),
  arr: ko.observableArray(['item1']),

  third: function(){

    return this.arr().join();
  }
};

ko.applyBindings(viewModel);

If I use the second approach, will I get the correct arr contents? Does the third variable get updated every time an item is added/removed from arr?

https://jsfiddle.net/zek2kz2b/5/

1

1 Answer 1

1

What's happening is that this in your computed isn't the view model so it doesn't have an arr method.

You need to provide your computed with the this context to use when it's invoked. You can do this by passing the view model a second parameter in your ko.computed call.

But because you're creating your view model as a plain object, you don't have the view model to pass in at the time you're calling ko.computed. So create your view model as a constructor function instead:

function ViewModel() {
  var self = this; // Capture the view model as self to simplify things
  self.name = ko.observable('test'),
  self.arr = ko.observableArray(['item1']),
  self.third = ko.computed(function(){
    return this.arr().join();
  }, self); // We now have the view model available to pass here
};
ko.applyBindings(new ViewModel());

Another way to do this is to simply reference the self reference to the view model in the computed:

function ViewModel() {
  var self = this;
  self.name = ko.observable('test'),
  self.arr = ko.observableArray(['item1']),
  self.third = ko.computed(function(){
    return self.arr().join();
  });
};
ko.applyBindings(new ViewModel());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.