Manual Annotating for Dependencies Injection

Manual Annotating for Dependency Injection

UnSafe from Minification

[Style Y090]
  • Avoid using the shortcut syntax of declaring dependencies without using a minification-safe approach.

    Why?: The parameters to the component (e.g. controller, factory, etc) will be converted to mangled variables. For example, common and dataservice may become a or b and not be found by Angular.

    /* avoid - not minification-safe*/
    angular
        .module('app')
        .controller('DashboardController', DashboardController);
    
    function DashboardController(common, dataservice) {
    }
    

    This code may produce mangled variables when minified and thus cause runtime errors.

    /* avoid - not minification-safe*/
    angular.module('app').controller('DashboardController', d);function d(a, b) { }
    

Manually Identify Dependencies

[Style Y091]
  • Use $inject to manually identify your dependencies for Angular components.

    Why?: This technique mirrors the technique used by ng-annotate, which I recommend for automating the creation of minification safe dependencies. If ng-annotate detects injection has already been made, it will not duplicate it.

    Why?: This safeguards your dependencies from being vulnerable to minification issues when parameters may be mangled. For example, common and dataservice may become a or b and not be found by Angular.

    Why?: Avoid creating in-line dependencies as long lists can be difficult to read in the array. Also it can be confusing that the array is a series of strings while the last item is the component’s function.

    /* avoid */
    angular
        .module('app')
        .controller('DashboardController',
            ['$location', '$routeParams', 'common', 'dataservice',
                function Dashboard($location, $routeParams, common, dataservice) {}
            ]);
    
    /* avoid */
    angular
      .module('app')
      .controller('DashboardController',
          ['$location', '$routeParams', 'common', 'dataservice', Dashboard]);
    
    function Dashboard($location, $routeParams, common, dataservice) {
    }
    
    /* recommended */
    angular
        .module('app')
        .controller('DashboardController', DashboardController);
    
    DashboardController.$inject = ['$location', '$routeParams', 'common', 'dataservice'];
    
    function DashboardController($location, $routeParams, common, dataservice) {
    }
    

    Note: When your function is below a return statement the $inject may be unreachable (this may happen in a directive). You can solve this by moving the Controller outside of the directive.

    /* avoid */
    // inside a directive definition
    function outer() {
        var ddo = {
            controller: DashboardPanelController,
            controllerAs: 'vm'
        };
        return ddo;
    
        DashboardPanelController.$inject = ['logger']; // Unreachable
        function DashboardPanelController(logger) {
        }
    }
    
    /* recommended */
    // outside a directive definition
    function outer() {
        var ddo = {
            controller: DashboardPanelController,
            controllerAs: 'vm'
        };
        return ddo;
    }
    
    DashboardPanelController.$inject = ['logger'];
    function DashboardPanelController(logger) {
    }
    

Manually Identify Route Resolver Dependencies

[Style Y092]
  • Use $inject to manually identify your route resolver dependencies for Angular components.

    Why?: This technique breaks out the anonymous function for the route resolver, making it easier to read.

    Why?: An $inject statement can easily precede the resolver to handle making any dependencies minification safe.

    /* recommended */
    function config($routeProvider) {
        $routeProvider
            .when('/avengers', {
                templateUrl: 'avengers.html',
                controller: 'AvengersController',
                controllerAs: 'vm',
                resolve: {
                    moviesPrepService: moviesPrepService
                }
            });
    }
    
    moviesPrepService.$inject = ['movieService'];
    function moviesPrepService(movieService) {
        return movieService.getMovies();
    }
    

Back to Table of Contents