I'm getting a "SCRIPT5002: Function expected" that only happens in IE. I'm currently testing against version 9. It happens when I use a previously defined computed observable inside of another computed observable.
My application is a bit more complex than this, so I've reproduced the error with the much simpler code below. The error happens on the line z = self.subtotal();
when you enter a number in for Number 1, Number 2, and Number 3 (and tab out).
This error does not occur in Chrome or Firefox and I've googled for quite a while. Hopefully someone can help un-stick me.
Here is the link to the jsfiddle: http://jsfiddle.net/kCmTg/
Here is the javascript:
function putVars() {
self = this;
self.number1 = ko.observable();
self.number2 = ko.observable();
self.subtotal = ko.computed(function () {
return parseFloat(self.number1()) + parseFloat(self.number2());
}, self, { deferEvaluation: true });
self.number3 = ko.observable();
self.number4 = ko.observable();
self.total = ko.computed(function () {
var x, y, z;
x = self.number3();
y = self.number4();
z = self.subtotal();
return parseFloat(x) + parseFloat(y) + parseFloat(z);
}, self, { deferEvaluation: true });
}
$(function () {
ko.applyBindings(new putVars());
});
Here is the html:
<h4>Calc 1</h4>
<label for="Number1">Number 1: </label><input id="Number1" type="text" data-bind="value: number1" />
<label for="Number2">Number 2: </label><input id="Number2" type="text" data-bind="value: number2" />
<label for="Subtotal"><b>Subtotal: </b></label><input id="Subtotal" type="text" data-bind="value: subtotal" readonly="readonly" />
<hr />
<h4>Calc 2</h4>
<label for="Number3">Number 3: </label><input id="Number3" type="text" data-bind="value: number3" />
<label for="Number4">Number 4: </label><input id="Number4" type="text" data-bind="value: number4" />
<label for="Total"><b>Total:</b> </label><input id="Total" type="text" readonly="readonly" data-bind="value: total" />
This has a similar cause to this one: knockout.js Computed observable called twice in Internet Explorer and is caused by the fact that in IE<10, Knockout has some special code to deal with getting an autocomplete value from the field. It does this even if the field is read-only as in your case. It does check, however, for the autocomplete
attribute. So you could fix it like this:
<input id="Subtotal" type="text" data-bind="value: subtotal" autocomplete="off" readonly="readonly" />
There is also a bug in Knockout at play here--that it will overwrite a computed observable passed to a two-way binding. This is already fixed in the development version of Knockout to be released as version 2.3.0 (probably in April 2013). To work around this, you can pass the value of the observable to the binding instead of the computed observable itself, like this:
<input id="Subtotal" type="text" data-bind="value: subtotal()" readonly="readonly" />
It appears you've discovered a bug in IE or KnockoutJS, likely exposed by Knockout's bindings, where Knockout is pushing a value into an observable, but in IE9, it overwrites the property.
This doesn't occur on IE10, suggesting it's a bug in IE9. I'd guess Knockout has something where it's checking if some value is a writable observable function and it's being reported incorrectly on IE9.
Interestingly, if you change KO computed to use a read/write, the error ceases:
self.subtotal = ko.computed({
read: function() {
return parseFloat(this.number1()) + parseFloat(this.number2());
},
write: function(val) { }
}, self);
Perhaps that is a sufficient work-around?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With