Knockout - write a value to a ko.computed

23,685

You need to specify a 'write' option in your ko.computed function. Please see the documentation on computed observables. Your binding handler has nothing to do with your value failing to update. Your computed should look something like this:

self.value = ko.computed({
    read: function () {
        return self.chosenAge().population; // 'fetched' from an array.
    },
    write: function (value) {
        //update your self.chosenAge().population value here
    },
    owner: self
});

Hope this helps.

Share:
23,685
leaksterrr
Author by

leaksterrr

Front-End Web Geek.

Updated on July 31, 2021

Comments

  • leaksterrr
    leaksterrr almost 3 years

    I've built a very data/number heavy app in Knockout. I'm currently getting the error:

    Uncaught Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.

    This is happening when my custom bindingHandler (which formats the numbers into 'large' form, ie. 123,345,678,987) tries to write back to the original input which displays the value of a computed function.

    Value displayed in an input element:

    self.value = ko.computed(function(){
        return self.chosenAge().population; // 'fetched' from an array.
    });
    

    Binding Handler:

    ko.bindingHandlers.largeNumber = {
        init: function(element, valueAccessor) {
            numberInit(element);
            var value = valueAccessor();
            var interceptor = ko.computed({
                read: function() {
                    // inject number formatting
                    return numeral(ko.unwrap(value)).format('0,0');
                },
                write: function(newValue) {
                    // remove formatting when writing a new value
                    value(numeral().unformat(newValue));
                }
            });
            // display new value in target element
            if(element.tagName.toLowerCase() == 'input' ) {
                ko.applyBindingsToNode(element, {
                    value: interceptor
                });
            }
            else {
                ko.applyBindingsToNode(element, {
                    text: interceptor
                }); 
            }
        }
    };
    
  • leaksterrr
    leaksterrr about 10 years
    Yeah I tried this originally, the issue I'm having is with writing it back? Not sure how to go about it
  • Zack Huber
    Zack Huber about 10 years
    Without some more information about your chosenAge object I can't really give you a good answer, could you update your post with more information on it?
  • Hp93
    Hp93 almost 7 years
    I think your code is incorrect, inside ko.computed should be an object, not a function. Also the link is outdated, the new link is knockoutjs.com/documentation/computed-writable.html
  • Julio Marins
    Julio Marins almost 7 years
    this is not even proper javascript