Reputation: 724
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).
Upvotes: 0
Views: 1951
Reputation: 11733
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>
Upvotes: 1