Knockoutjs formatCurrency function not working in view

Copied the formatCurrency function from the Knockoutjs cart editor sample at http://knockoutjs.com/examples/cartEditor.html, but cannot get it to work in the view like the example. It works when I call it from the view model though. I was also able to copy a currency binding handler and that works. My view and view model is below.

<span>Total salary: </span><span data-bind="text: totalSalary"></span><br />
<span>Total salary: </span><span data-bind="currency: totalSalary, symbol: '$'"></span><br />
<span>Total salary: </span><span data-bind="text: totalFormattedSalary"></span><br />
<span>Total salary: </span><span data-bind='text: formatCurrency(totalSalary)'></span>

and view model:

// from http://tech.pro/blog/1863/10-knockout-binding-handlers-i-don-t-want-to-live-without
ko.bindingHandlers.currency = {
    symbol: ko.observable('$'),
    update: function(element, valueAccessor, allBindingsAccessor){
    return ko.bindingHandlers.text.update(element,function(){
        var value = +(ko.utils.unwrapObservable(valueAccessor()) || 0),
        symbol = ko.utils.unwrapObservable(allBindingsAccessor().symbol === undefined
                ? allBindingsAccessor().symbol
                : ko.bindingHandlers.currency.symbol);
        return symbol + value.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
    });
    }
};

function formatCurrency(value) {
    return "$" + value.toFixed(2);
};

var Teacher = function(id, name, salary) {
    this.id = id;
    this.name = name;
    this.salary = salary;
};

var viewModel = function(teachers) {
    var self = this;
    self.teachers = ko.observable(teachers);
    self.totalSalary = ko.computed(function() {
        var total = 0;
        $.each(self.teachers(), function() { total += this.salary; });
        return total;
    });
    self.totalFormattedSalary = ko.computed(function() {
        var total = 0;
        $.each(self.teachers(), function() { total += this.salary; });
        return formatCurrency(total);
    });
};

var initialTeachers = [
    new Teacher(1, "Tom", 40000),
    new Teacher(2, "Bill", 41000),
    new Teacher(3, "Bob", 42000)
];

var vm = new viewModel(initialTeachers);
ko.applyBindings(vm);

JSFiddle

TIA, Steve

EDIT: if you hit F12 in Chrome, it's returning the error: "Uncaught ReferenceError: Unable to process binding "text: function (){return formatCurrency(totalSalary) }" Message: formatCurrency is not defined" where it's trying to call that function from the view. If you remove that last line in the view, no errors.

Upvotes: 1

Views: 3817

Answers (1)

Explosion Pills
Explosion Pills

Reputation: 191749

totalSalary is an observable. You have to get it by calling it as a function

formatCurrency(totalSalary())

http://jsfiddle.net/wape5ts8/31/

The undefined is not a function is from .toFixed being called on the totalSalary observable which is a function.

Upvotes: 4

Related Questions