0

I am trying to create a computed variable (RateDisplay) based on what the user enters(MinRate, MaxRate if VRAChecked is true, else FlatRate) that is defined as an observable. I have an object (product) as part of the viewmodel like the following:

var viewModel = new function () {

var self = this;
self.Id = ko.observable();

self.product = {
  Id: ko.observable(),
  Name: ko.observable(),
  VRAChecked: ko.observable(false),
  MinRate: ko.observable(),
  MaxRate: ko.observable(),
  FlatRate: ko.observable(),
  RateDisplay: ko.computed(function() {
    if (self.product.VRAChecked())
      {
        return self.product.MinRate() + "-" + self.product.MaxRate();
      }
      else
      {
        return self.product.FlatRate();
      }
  }, this),

  PercentageGoal: ko.observable()
};

  };//viewmodel ends

The problem is, I get this js error: "self.product is undefined" at the line

  if (self.product.VRAChecked())

I understand that, that is probably because the object is still being created.

So, how do I create the computed variable (RateDisplay)? I need it to be an element of that object (product).

1 Answer 1

1

The problem is that you're creating the computed before the other product properties are even created, and then, they are not defined yet.

Try to create it only after the product declaration, and it will work like a charm.

Take a look at the example below:

var viewModel = function() {
  var self = this;
  self.Id = ko.observable();
  self.product = {
    Id: ko.observable(),
    Name: ko.observable(),
    VRAChecked: ko.observable(false),
    MinRate: ko.observable(),
    MaxRate: ko.observable(),
    FlatRate: ko.observable(),
    PercentageGoal: ko.observable()
  };
  
  self.product.RateDisplay = ko.computed(function() {
      if (self.product.VRAChecked()) {
        return self.product.MinRate() + "-" + this.product.MaxRate();
      } else {
        return self.product.FlatRate();
      }
    }, self)
}

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div>
  <label>Min Rate <input type="textbox" data-bind="value: product.MinRate"></label>
  <label>Max Rate <input type="textbox" data-bind="value: product.MaxRate"></label>
</div>
<div>
  <label>Flat Rate <input type="textbox" data-bind="value: product.FlatRate"></label>
</div>
<div>
  <label><input type="checkbox" data-bind="checked: product.VRAChecked"> VRA Checked</label>
</div>
<div>Display: <span data-bind="text: product.RateDisplay"></span></div>

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.