At commit bb14dc409f7521cb79498 if you load up the CHI end wiht minification on you'll get the following error:
Error: [$injector:unpr] Unknown provider: eProvider <- e
Here is how I used the ng-strict-di directive to find the cause. In this case the page was loading and data was being retrieved so I was able to zero in on it being something non-critical for page function, this led me to look for directives in the actual templates. I commented out the %toaster-output directive in chi.index.histor.html.haml and the error went away. However, when I looked into that directive I couldn't find any missing dependencies in between the $inject = [] and the actual function definitions.
Here is where ng-strict-di helps.
First add ng-strict-di to the application element (here it is in source/chi/index.html.haml)
!!!5
%html{"ng-app" => "chi", "ng-strict-di"=>true}
%head
When you run minified with this change you'll get a new error:
Error: [$injector:strictdi] e is not using explicit annotation and cannot be invoked in strict mode
The nice thing here is that this will fail now, even if minification is turned off, so I re-ran middleman with no_cssmin set and when I load the page, this is the new error:
Error: [$injector:strictdi] controller is not using explicit annotation and cannot be invoked in strict mode
This error only looks marginally helpful because the method name is controller, but it is helpful enough, in the definition for the toaster-output directive the controller method is named controller (that's a gross name). To verify that this is actually where the problem is happening, I updated the controller method name to be better:
(function(){
'use strict';
angular
.module('common')
.directive('toasterOutput', toasterOutput);
toasterOutput.$inject = [];
function toasterOutput(){
return {
restrict: 'E',
templateUrl: '/templates/modules/chi/notification-banner.html',
scope: {},
controller: toasterOutputController,
controllerAs: 'controller'
};
toasterOutputController.$inject = ['$scope', 'commonToaster'];
function toasterOutputController($scope, commonToaster){
var vm = this;
vm.closeToast = closeToast;
$scope.toasts = commonToaster.getToasts();
activate();
function activate(){
$scope.$watch(
function(){return commonToaster.getToasts().length;},
function(){
commonToaster.markAllAsShown();
$scope.toasts = commonToaster.getToasts();
});
}
function closeToast(id){
commonToaster.removeToast(id);
}
}
}
})();
Which now yields the error:
Error: [$injector:strictdi] toasterOutputController is not using explicit annotation and cannot be invoked in strict
So the problem is with the dependencies on the toasterOutputController, which are declared via $inject, so why isn't it working. The problem is that the line toasterOutputController.$inject = [];
is an executable line, not a declarative line and it comes after the return statement for it's containing function, easy mistake to make in the Angular.
There was another problem on that page as well. When you click the Quick View button for a delivered CHI, you'd get an unknown tProvider <- t
error. It happend right on click, and digging into the code reveals that the only thing that happens there is a state change, I dug into the state change and the controller that should have been responsible was never loading (added console.log to the method that is registered for the controller). Running with ng-strict-di yields the message: onEnter is not using explicit annotation and cannot be invoked in strict mode
, so I started at the routes file and dug into dependencies from there. It turns out that statefulModalProvider defines an onEnter with $inject dependencies and the problem was the same. The onEnter.$inject = [...];
was happening after the return statement for the function.
- give your methods good names even if they are local, make them easy to grep.
- make sure you aren't trying to annotate methods with $inject in unreachable places.
- ng-strict-di will surface minification di errors before deploy in non-minified code (how we usually develop)
Thanks! It helped