angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.81k stars 27.5k forks source link

Expression throws JS error on attempt to invoke non-fn as fn #14072

Open royaldark opened 8 years ago

royaldark commented 8 years ago

In expressions, undefined or null references are supposed to short-circuit evaluation, resulting in an undefined value, but no ReferenceError or TypeError. Therefore, invoking an expression $ctrl.x() should not give an error if $ctrl.x is undefined. Great.

If, however, $ctrl.x = 4 (or any other non-undefined|null|function value), invoking $ctrl.x() gives a very hard-to-track Error: v2.x is not a function, which leads to the bowels of ASTCompiler.prototype.compile

Is this intentional, or should this bail out with undefined? Although it ultimately helped me find an issue with my code, it was extremely hard to trace (the offending fn call had a name very commonly used in our project).

See this Plunkr for a demonstration: http://plnkr.co/edit/0OnZCNnaGhrsObJZ6uBU?p=preview

I am using Angular 1.5.0.

Narretz commented 8 years ago

I think it's correct to throw in this case because you are calling a non-function. Angular's forgiveness for expressions is only for undefined / nulled values, because that's common with async operations. Simply logging undefined when you are calling a non-function would be quite confusing. But maybe we can make the error message better.

lgalfaso commented 8 years ago

Agree with @Narretz, having something that is not undefined and is being called as a function implies that there is something wrong. Trowing an error sounds fine, but agree that the error needs some help.