0

I have a function and this is the code:

this.federalPriceComputed = ko.pureComputed(
        function() {
            return ko.utils.arrayMap(this.lineItems(), function(item) {
                var total = item.price() * item.federalTax()
                return formatCurrency(total);
            });
        }, this
    ).extend({ throttle: 500 });

this.statePriceComputed = ko.pureComputed(
            function() {
                return ko.utils.arrayMap(this.lineItems(), function(item) {
                    var total = item.price() * item.stateTax()
                    return formatCurrency(total);
                });
            }, this
        ).extend({ throttle: 500 });

When i run my code it says statePriceComputed is not defined.

I am trying to keep all my code inside the model object.

If I do this, it works.

ko.utils.arrayForEach(myModel.lineItems(), function(item) {
   item.federalPriceComputed = ...
   item.statePriceComputed = .... 
   }
);

More information:

ko.observableArray.fn.withIndex = function (keyName) {  
    "use strict";
    var index = ko.computed(function () {
        var list, keys;
        list = this() || [];    // the internal array
        keys = {};              // a place for key/value
        ko.utils.arrayForEach(list, function (v) {
            if (keyName) {          // if there is a key
                keys[ko.utils.unwrapObservable(v[keyName])] = v;    // use it
            } else {
                keys[v] = v;
            }
        });
        return keys;
    }, this);

    // also add a handy add on function to find
    // by key ... uses a closure to access the 
    // index function created above
    this.findByKey = function (key) {
        return index()[key];
    };

    return this;
};

When i bind the variable i did it like this

    if (stateTax.length) {
       stateTax.attr("data-bind", "text: formatCurrency($data.lineItems.findByKey(\"" + itemId + "\").statePriceComputed())");
    }

// similar code for federal tax

Can you give suggestion why option #1 does not work.

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
Chun ping Wang
  • 3,879
  • 12
  • 42
  • 53
  • You have provided quite a bit of code, but not quite an actual repro. Please boild down the code to the actual issue and show all (though as little as possible) code required to reproduce it in the question, preferably in a Stack Snippet. – Jeroen May 05 '15 at 13:16
  • On a more general note, you should check out [the `var self = this;` idiom](http://stackoverflow.com/q/337878/419956), because I feel you may have quite a few "`this`" issues. – Jeroen May 05 '15 at 13:18

1 Answers1

0

Then you must have done something wrong? The snippet below shows #1 suggestion working..

function myApp(items) {
  this.lineItems = ko.observableArray(items || []);
  this.federalPriceComputed = ko.pureComputed(function() {
    return ko.utils.arrayMap(this.lineItems(), function(item) {
      var total = item.price() * item.federalTax();
      return total; });
  }, this).extend({ throttle: 500 });
  this.statePriceComputed = ko.pureComputed(function() {
    return ko.utils.arrayMap(this.lineItems(), function(item) {
      var total = item.price() * item.stateTax();
      return total; });
  }, this).extend({ throttle: 500 });
}

var app = new myApp([
  {price: ko.observable(5), stateTax: ko.observable(21), federalTax: ko.observable(2)},
  {price: ko.observable(6), stateTax: ko.observable(12), federalTax: ko.observable(2)},
  {price: ko.observable(10), stateTax: ko.observable(12), federalTax: ko.observable(3)},
  {price: ko.observable(50), stateTax: ko.observable(21), federalTax: ko.observable(4)},
  {price: ko.observable(8), stateTax: ko.observable(12), federalTax: ko.observable(2)},
  {price: ko.observable(75), stateTax: ko.observable(21), federalTax: ko.observable(3)}]);

ko.applyBindings(app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div style="float: left; width: 50%;">
<h3>Federal Price</h3>
<div data-bind="foreach: federalPriceComputed">
  <div data-bind="text: $data"></div>
</div>
</div>
<div style="float: left; width: 50%;">
<h3>State Price</h3>
<div data-bind="foreach: statePriceComputed">
  <div data-bind="text: $data"></div>
</div>
</div>
webketje
  • 10,376
  • 3
  • 25
  • 54