Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

knockout.js

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);
like image 777
user1125489 Avatar asked Feb 23 '26 02:02

user1125489


1 Answers

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);
like image 166
Martin Devillers Avatar answered Feb 27 '26 04:02

Martin Devillers