Search code examples
knockout.jsknockout-2.0

Why is my knockoutjs computed observable not working?


I can't seem to have a computed value of this working. any input would be appreciated.

i get the values for my prices from server.

 var pModel = function () {
     var self = this;
     self.prices = ko.observable({ "ID": 1,"Price1": 12,"Price2": 12});

     self.Total = ko.computed(function () {
         var total = 0;
         total = self.prices().Price1 + self.prices().Price2;
         return total;
     });
 };
 var VModel = new pModel();
 ko.applyBindings(VModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js"></script>
<form action='/someServerSideHandler'>
    <table>
        <thead>
            <tr>Prices</tr>
        </thead>
        <tbody id="calc">
            <tr>
                <td>Price 1</td>
                <td>
                    <input data-bind='value: prices().Price1' />
                </td>
            </tr>
            <tr>
                <td>price 2</td>
                <td>
                    <input data-bind='value: prices().Price2' />
                </td>
            </tr>
            <td>TOTAL</td>
            <td> <span data-bind="text: $root.Total"></span>
            </td>
        </tbody>
    </table>
</form>


Solution

  • Your prices variable is observable, but its members aren't. Redefine it like this:

     self.prices = ko.observable({
         ID: ko.observable(1),
         Price1: ko.observable(12),
         Price2: ko.observable(12)
     });
    

    Now, this almost works, but if you change the values, it'll convert them to strings, so the total of 18 and 12 will be 1812! We'll need to turn those strings into numbers.

     self.Total = ko.computed(function () {
         var price1 = parseFloat(self.prices().Price1());
         var price2 = parseFloat(self.prices().Price2());
         return price1 + price2;
     });
    

    You should be all set!