Angular.js Best Practices


JavaScript is a very flexible language so you can generally do anything in a number of different ways, but like any language there are a number of patterns that will contribute towards a more maintainable result.  I've read quite a few articles, blogs and documents stating lists of Angular best practices and here are some of things I think are very important to writing clean, modular code.

File Structure

Structure your application by feature, not by angular component type.  Developers will have an easier time finding the appropriate code as it's more organized, organizing by angular component type creates 'buckets' of unrelated code.


Small Modules

It's better to have many small modules than fewer bigger modules .  Angular modules can be thought of similarly to a namespace in other languages like C#, C++, Java, etc.  It's better to keep a smaller number of related components in them then in a larger more general module, for example 'users,' 'products,' 'login,' instead of 'components,' 'shared,' 'utility.'  This is very similar and actually mirrors the file structure practice and will make it so developer's will have an easier time finding the appropriate code.

Thin Controllers

Keep your controller code thin, don't put much (if any) business logic in them.  Controllers are generally (but not always) tied to a particular piece of user interface and don't lend themselves to re-use nearly as much as a service, provider or filter which can be injected into any controller or used any UI in the case of a filter.

Use IIFE's for a more modular 'feel'

Angular code can be written in many different styles, a few examples are:

Using variables:

  var module = anguar.module('myModule');
  module.controller('controller', function($scope, $log) {

       // ... 
  });

Chaining syntax:  

  angular.module('myModule')
              .controller('myController', function($scope, $log) { 
         // ... 
   });
  
Immediately Invoked Function Expressions (IIFEs)

In recent days I've seen more examples using the more modular looking IIFE approach and out of the different styles I've seen I think I like this one best:

    (function(myModule){

        module.controller('myController', ['$scope', '$log', 'userService', 

             function($scope, $log, userService) {
                 // ...
        }]);

    })(angular.module('myModule');



Write min-safe code

In many languages dependency injection is a pattern used to inject loosely coupled components into a system, often by defining an interface and passing in an object that implements that interface making
it type safe.  In JavaScript however there are no interfaces (as of the writing of this article) and you can pass any type into any parameter since it's a dynamically typed language. To solve this dilemma Angular's dependency injection works by name which makes things simple for development but throws a wrench in the works when the code is minified for optimization.

Imagine the following scenario:

    module.controller('loginController', 
             function($scope, $log, userService){ 
       // ... 
   });
  

Once minified could turn into

    module.controller('loginController', 
             function(a, b, c){ 
       // ... 
   });

Since Angular's dependency injection works by name, it'd have no idea what providers and services to pass to the controller anymore.

In order to get around this issue Angular introduced another way to pass parameter to your Angular components, passing everything in as array:


    module.controller('loginController', 
            ['$scope', '$log', 'userService', 
                function($scope, $log, userService){
       // ... 
    }]);
  

Now even when the parameter names get minified, angular still knows what to inject.

Debug Tools

Lastly, there quite a few helpful debug tools geared towards Angular development.  Batarang and NG-Inspector both provide really helpful feature for viewing scope data and make Angular development easier.  They'll probably save you a few console.log statements:

Batarang
NG-Inspector

(Ng-inspector screen shot)




References

Google's Angular Best Practices
John Pappa's Style Guide
Top 10 Mistakes Angular Developers Make
Angular Directory Structure (Scotch.io)