For this guide, adhere to the Angular 2 Style Guide or the Angular 1 Style Guide unless stated below, which supersedes those rules.

Topics for this document are in the same order as they are in the Angular 1 Style Guide.

IIFE

IIFE for every component. A build procedure should compile all files into one file, duplicate "use strict;" lines are eliminated one is inserted at the top and finally the file is minified. This is possible because no global variables are used within the Angular scope. It is bad practice to use them and nearly forbidden when developing an Angular application.

Generate code without using superfluous IIFEs.

// controller.js
"use strict";


/**
 * Describe controller's purpose.
 *
 * @param {module~dependency} dependency
 */
angular.module("module").controller("SessionsController", (dependency) => {
    var variable1, variable2;


    /**
     * Describe function's purpose.
     */
    function gotoSession() {
      /* */
    }


    /**
     * Describe function's purpose.
     */
    function refresh() {
      /* */
    }


    /**
     * Describe function's purpose.
     */
    function search() {
      /* */
    }

    this.gotoSession = gotoSession;
    this.refresh = refresh;
    this.search = search;
    variable1 = [];
    variable2 = 'Sessions';
});

If needing an activation function as can be the case when invoking a controller for a directive, wrap everything within an activate function.

// controller.js
"use strict";


/**
 * Describe controller's purpose.
 *
 * @param {module~dependency} dependency
 */
angular.module("module").controller("SessionsController", (dependency) => {
    this.activate = () => {
        /**
         * Describe function's purpose.
         */
        function gotoSession() {
          /* */
        }


        /**
         * Describe function's purpose.
         */
        function refresh() {
          /* */
        }


        /**
         * Describe function's purpose.
         */
        function search() {
          /* */
        }

        this.gotoSession = gotoSession;
        this.refresh = refresh;
        this.search = search;
        variable1 = [];
        variable2 = 'Sessions';
    };
});

Controllers

Our goal is to make things more explicit and obvious.

controllerAs with vm

Supersedes the topics presented in the controllerAs with vm section.

We don’t require the use of using a variable like vm within a controller, properties and methods can be assigned to this when they need to. Just make sure to only assign to this what needs to be accessible.

Bindable Members Up Top

Supersedes some topics presented in the Bindable Members section.

We don’t want all the bindable members at the top if it calls a function as the called functions shouldn’t be called before they are defined. Refer above for example on how to structure code in regards to placement of methods and properties.

Assigning Controllers

Supersedes some topics presented in the Assigning Controllers section.

If a controller is to be assigned within a view, it should be put into the template. This makes it easier and everything is contained within the template and module.

// config.js
"use strict";

function config($routeProvider) {
    $routeProvider
        .when("/games", {
            templateUrl: "app/game/games.html"
        });
}

angular.module("app").config(config);

Template:

<!-- games.html -->
<div ng-controller="GamesController as games">
</div>

Services and Factories

Services and Factories are formatted the same way and only return the collection of functions that should be visible from outside.

// factory.js
/**
 * Describe the type.
 *
 * @typedef {Object} module~factory
 * @property {Function} function1
 * @property {Function} function2
 */
"use strict";

/**
 * Describe factory's purpose.
 *
 * @return {module~factory}
 */
angular.module("app").factory("service", () => {
    /**
     * Describe function's purpose.
     */
    function function1 () {
        /* */
    }


    /**
     * Describe function's purpose.
     */
    function function2 () {
        return function3();
    }


    /**
     * Describe function's purpose.
     */
    function function3 () {
        /* */
    }

    return {
        function1,
        function2
    }
});

Directives

There is no need to format the directive by returning a variable. This is a waste of memory and lines as there is nothing being done with the variable except to return it.

// directive.js
"use strict";

/**
 * Describe the directive's purpose.
 *
 * @return {angular~directive}
 */
function directive () {
    return {
        bindController: true,
        controller: "ControllerController",
        controllerAs: "vm",
        restrict: "AE",
        scope: {
            // scope properties
        },
        templateUrl: "path/to/tempate.html"
    }

    angular.module("module").directive("directive", directive);
}

Manual Annotating for Dependency Injection

We are removing manual processes and repeat code.

Manually Identify Dependencies

Dependencies shouldn’t use $inject since we can inject the dependencies in the primary function when declaring the component.

// controller.js
"use strict";

/**
 * Describe the controller's purpose.
 *
 * @param {angular~$scope} $scope
 * @param {module~dependency} dependency
 */
angular.module("module").controller("SessionsController", ($scope, dependency) => {
// truncated to callout top section

Resolving Promises

Having promises inside controllers is a good thing, but we don’t want to have them in routes, as controllers and their functionality will be defined in static HTML or within a directive.

Route Resolve Promises

This is unnecessary, since the controller should be only included in the directive or element. This again keeps the code clean and functionality contained in the module.

JSHint and JSCS

Supersedes some topics presented in the JS Hint and JSCS sections.

We’ve decided to use ESLint instead of JS Hint. This provides us basically the same functionality, but we liked the customizability more. Refer to the ESLint Style Guide Section for more information on using ESLint. ESLint also gives the capabilities of what JSCS supplies since they have merged.