user1125489
user1125489

Reputation: 103

knockout.js - mapping plugin - how to add ko.computed function

I am trying to get this to work but am not doing something right. I am using knockout, taking a json response and mapping it for a checkout cart, what I am not able to do is add a function after to add the sum of the product prices. see below for an idea of what I am trying to do,

full fiddle is here.. http://jsfiddle.net/justayles/Jeaua/26/

var jsonCart = {
    "globalshipping": 1.00,
    "globaltax": 5.00,
    "productitem": [
    {
        "img": '/Content/img/notavailable.jpg',
        "produrl": 'http://www.google.com',
        "prodtitle": 'Product1',
        "opt1": 'colour',
        "opt2": 'size',
        "qty": 3,
        "unitprice": 10.00,
        "shippingcost": 0.00,
        "like": true,
        "likediscount": 10,
        "taxable": true
    },
    {
        "img": '/Content/img/notavailable.jpg',
        "produrl": 'http://www.google.com',
        "prodtitle": 'Product1',
        "opt1": 'colour',
        "opt2": 'size',
        "qty": 1,
        "unitprice": 33.00,
        "shippingcost": 0.00,
        "like": false,
        "likediscount": 0,
        "taxable": false
    },
    {
        "img": '/Content/img/notavailable.jpg',
        "produrl": 'http://www.yahoo.com',
        "prodtitle": 'Product1',
        "opt1": 'colour',
        "opt2": 'size',
        "qty": 5,
        "unitprice": 21.00,
        "shippingcost": 0.00,
        "like": true,
        "likediscount": 10,
        "taxable": true
    }
    ]
};

var mappingOptions = {
    'productitem': {
        // overriding the default creation / initialization code
        create: function (options) {

            return (new (function () {

                // setup the computed binding
                this.calcPrice = ko.computed(function () {
                    return this.unitprice() * this.qty();
                }, this);

                ko.mapping.fromJS(options.data, {}, this);
            })(/* call the ctor here */));
        }
    }
};


var viewModel = ko.mapping.fromJS(jsonCart, mappingOptions );

viewModel.grandTotal = ko.computed(function() {
    var result = 0;
    ko.utils.arrayForEach(this.productitem, function(item) {
        result += item.calcPrice;
    });
    return result;
}, viewModel);

console.log(viewModel);

ko.applyBindings(viewModel);

Upvotes: 3

Views: 3306

Answers (1)

Martin Devillers
Martin Devillers

Reputation: 18012

Fixed: http://jsfiddle.net/Jeaua/27/

You forgot parentheses on your productitem and calcPrice observables. Remember, ko.mapping turns arrays into observable arrays and values into observable values. These need to be called as functions in order to retrieve their actual value.

viewModel.grandTotal = ko.computed(function() {
        var result = 0;
        ko.utils.arrayForEach(this.productitem() /* parentheses */, function(item) {
            result += item.calcPrice(); /* parentheses */
        });
        return result;
}, viewModel);

Upvotes: 4

Related Questions