I'm still learning AngularJS, which means I can get stuff done but I'm dangerous. A few days ago I ran into a problem that drove me crazy. I was trying to use ngCordova in an existing AngularJS application and kept running into a problem injecting the library into my controller. The error message was less than helpful. Heck, it was useless. Let's look at an example.
I grabbed a copy of the AngularJS seed project (https://github.com/angular/angular-seed) to create a quick simple AngularjS application. (Before this I tried yeoman but after thirty minutes of fighting it and it hanging I decided to give up.) I then set the application to use the minified version of the AngularJS library. That's the key. Then I opened up one of the JavaScript files and modified the dependencies to include something bad (literally):
'use strict';
angular.module('myApp.view1', ['ngRoute','somethingbad'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', [function() {
}]);
The error reported by AngularJS was this:
Error: [$injector:modulerr] http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=myApp&p1=%5B%24injector%3Amodulerr%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.28%2F%24injector%2Fmodulerr%3Fp0%3DmyApp.view1%26p1%3D%255B%2524injector%253Amodulerr%255D%2520http%253A%252F%252Ferrors.angularjs.org%252F1.2.28%252F%2524injector%252Fmodulerr%253Fp0%253Dsomethingbad%2526p1%253D%25255B%252524injector%25253Anomod%25255D%252520http%25253A%25252F%25252Ferrors.angularjs.org%25252F1.2.28%25252F%252524injector%25252Fnomod%25253Fp0%25253Dsomethingbad%25250Az%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A6%25253A450%25250AYc%25252Fb.module%25253C%25252F%25253C%25252Fb%25255Be%25255D%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A20%25253A1%25250AYc%25252Fb.module%25253C%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A20%25253A1%25250Ae%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A267%25250Ar%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A7%25253A288%25250Ae%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A207%25250Ae%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A284%25250Ar%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A7%25253A288%25250Ae%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A207%25250Ae%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A284%25250Ar%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A7%25253A288%25250Ae%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A33%25253A207%25250Aec%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A36%25253A309%25250Adc%25252Fc%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A18%25253A170%25250Adc%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A18%25253A387%25250AWc%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A17%25253A415%25250A%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A216%25253A78%25250Aa%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A146%25253A93%25250Ane%25252Fc%25252F%25253C%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A31%25253A223%25250Ar%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A7%25253A288%25250Ane%25252Fc%252540http%25253A%25252F%25252Flocalhost%25253A8000%25252Fapp%25252Fbower_components%25252Fangular%25252Fangular.min.js%25253A31%25253A207%25250A%250Az%252F%253C%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A6%253A450%250Ae%252F%253C%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A34%253A97%250Ar%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A288%250Ae%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A33%253A207%250Ae%252F%253C%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A33%253A284%250Ar%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A288%250Ae%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A33%253A207%250Ae%252F%253C%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A33%253A284%250Ar%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A288%250Ae%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A33%253A207%250Aec%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A36%253A309%250Adc%252Fc%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A18%253A170%250Adc%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A18%253A387%250AWc%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A17%253A415%250A%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A216%253A78%250Aa%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A146%253A93%250Ane%252Fc%252F%253C%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A31%253A223%250Ar%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A7%253A288%250Ane%252Fc%2540http%253A%252F%252Flocalhost%253A8000%252Fapp%252Fbower_components%252Fangular%252Fangular.min.js%253A31%253A207%250A%0Az%2F%3C%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A6%3A450%0Ae%2F%3C%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A34%3A97%0Ar%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A288%0Ae%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A33%3A207%0Ae%2F%3C%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A33%3A284%0Ar%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A288%0Ae%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A33%3A207%0Aec%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A36%3A309%0Adc%2Fc%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A18%3A170%0Adc%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A18%3A387%0AWc%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A17%3A415%0A%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A216%3A78%0Aa%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A146%3A93%0Ane%2Fc%2F%3C%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A31%3A223%0Ar%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A288%0Ane%2Fc%40http%3A%2F%2Flocalhost%3A8000%2Fapp%2Fbower_components%2Fangular%2Fangular.min.js%3A31%3A207%0A angular.min.js:6
Yeah, have fun with that. In case you don't feel like scrolling over the entire thing, I'll save you the trouble and say it basically is gibberish to anyone who doesn't have a computer as a brain. So I struggled with this for a while until a random StackOverflow post (sorry, forgot to bookmark it!) mentioned that using the minified version of the AngularJS library actually changes how errors are reported. That seemed.... odd. But for the heck of it I switched back. The result is incredibly improved:
Error: [$injector:modulerr] Failed to instantiate module myApp due to:
[$injector:modulerr] Failed to instantiate module myApp.view1 due to:
[$injector:modulerr] Failed to instantiate module somethingbad due to:
[$injector:nomod] Module 'somethingbad' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.2.28/$injector/nomod?p0=somethingbad
minErr/<@http://localhost:8000/app/bower_components/angular/angular.js:78:12
module/<@http://localhost:8000/app/bower_components/angular/angular.js:1677:1
ensure@http://localhost:8000/app/bower_components/angular/angular.js:1601:38
module@http://localhost:8000/app/bower_components/angular/angular.js:1675:1
loadModules/<@http://localhost:8000/app/bower_components/angular/angular.js:3877:22
forEach@http://localhost:8000/app/bower_components/angular/angular.js:325:9
loadModules@http://localhost:8000/app/bower_co angular.js:78
In my particular case, it was a bug in ngCordova's custom build code where the top level module couldn't load a lower level module. Switching to the non-minified version fleshed this out immediately.
I have to be honest - I can't imagine why error reporting is something you would get rid of in minification. I guess the hope is that you don't have errors like this in production but I know I never would have guessed this. I typically use the minified version of frameworks like this as I don't expect to need to inspect/debug the library itself. Does anyone know if other frameworks (Ember, etc) also do this?