Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KnockoutJS catch errors Binding

I want to catch an error, correct it and continue executing the program. http://jsfiddle.net/Gthv9/12/

But, I can't do it!

If you click on: "re Check On Model1", "re Check On Model3" - it's ok.

If you click on: "re Check On Model1", "re Check On Model2", "re Check On Model3" - there's an error.

Uncaught Error: Unable to parse bindings.
Message: ReferenceError: name3 is not defined;
Bindings value: text: name3 

Why?

I wrapped the problem code in a try-catch block (viewModel.recheckData2() ), but, the application crashes on clicking viewModel.recheckData3() !

I know that knockoutJS stores the error state (new model2()), but don't know what I should do.

How can I catch the error properly?

Thanks!

like image 750
zoh Avatar asked Oct 30 '12 10:10

zoh


2 Answers

I am not sure that I understand your exact goal, but Knockout will stop binding when it runs into this type of an issue.

If your issue is simply undefined variables, then one trick that you can use is to bind against $data.name3 rather than just name3. Accessing a undefined property off of a valid object does not cause an error.

If you really want something more robust, then you could consider using a custom binding provider.

For example, you could write a quick wrapper to the real binding provider like:

var ErrorHandlingBindingProvider = function() {
    var original = new ko.bindingProvider(); 

    //determine if an element has any bindings
    this.nodeHasBindings = original.nodeHasBindings;

    //return the bindings given a node and the bindingContext
    this.getBindings = function(node, bindingContext) {
        var result;
        try {
            result = original.getBindings(node, bindingContext);
        }
        catch (e) {
            if (console && console.log) {
                console.log("Error in binding: " + e.message);   
            }
        }

        return result;
    };
};

ko.bindingProvider.instance = new ErrorHandlingBindingProvider();

This would catch errors, log them, and proceed. Of course the element that had this "bad" binding would not bound. If there is some known way that you want to handle it, then you could add that logic after catching the error. Maybe you want to inspect that element (node) and the bindingContext to determine what needs to be done.

Sample: http://jsfiddle.net/rniemeyer/KxXqs/

UPDATE: Here is a version for 3.0+ that traps/logs errors in binding syntax as well as errors when the bound value is actually evaluated. http://jsfiddle.net/rniemeyer/ecbn1dmy/

like image 83
RP Niemeyer Avatar answered Sep 17 '22 07:09

RP Niemeyer


I added another line to the error handler from @RPNiemeyer to console the node causing the error in the catch block - makes it really easy to find an error on a complex page:

if (console && console.log) {
            console.log("Error in binding: " + e.message);
            console.log("Node causing error:");
            console.log(node);
        }
like image 33
Jeremy Noble Avatar answered Sep 17 '22 07:09

Jeremy Noble