In Search of AngularJS Best Practices
One of my favorite things about AngularJS is that it creates a nice structure for a project’s JavaScript code. Its architecture encourages best software practices by allowing us to separate different components of the app in a logical way. Its HTML manipulation tools, as well as two-way data-binding, are also very intuitive and greatly simplify the development process.
What surprised me as I started getting into Angular development, though, is how many different ways there are to do certain basic things. Angular has a very active development community and new features being added all the time. Occasionally even design principles and accepted practices go through significant change. Angular 2 is a good example – despite the name, it’s basically a completely new framework with different architecture and design philosophy!
What makes it more difficult is that there’s no universally accepted standard or styleguide for Angular (in fact not just Angular, but JavaScript). So a developer might find it problematic at first to figure out which practices to follow.
One example of differing approaches is binding a variable to controller. The official tutorial tells you that you need to do it by injecting a $scope
service to your controller, and then attaching the items you want to be able to access/manipulate in your HTML template:
<div ng-app="myApp" ng-controller="MainCtrl"> <p> First Name: {{ firstName }}</p> <p> Last Name: {{ lastName }}</p> </div>
/* main.js */ angular .module('myApp') .controller('MainCtrl', ['$scope', function ($scope) { $scope.firstName = 'John'; $scope.lastName = 'Smith'; }]);
But then, if you check other sections of the official documentation, you’ll notice that sometimes the variables are bound to the controller directly, using so-called “Controller As” syntax:
<div ng-app="myApp" ng-controller="MainCtrl as ctrl"> <p> First Name: {{ ctrl.firstName }}</p> <p> Last Name: {{ ctrl.lastName }}</p> </div>
/* main.js */ angular .module('myApp') .controller('MainCtrl', function () { var self = this; self.firstName = 'John'; self.lastName = 'Smith'; });
You might also see “vm” used instead of ctrl or self: “ng-controller=”MainCtrl as vm”. This version is recommended by this styleguide. “vm” stands for View Model.
So, which is the right way? Well, “Controller As” is a latter addition and it is considered somewhat better practice. It also makes it more explicit as to which controller a variable in the view belongs. And yet, you will see lots of projects that are using $scope
. In fact, the official API guide is using both ways in their examples.
Another example – below, the controller function is defined as a last element in the array.
angular .module('myApp') .controller('MainCtrl', ['$scope', function ($scope) { ...
This is an array syntax for safe dependency injection – the reason for it is that minification/uglification renames all the variables. As a result, AngularJS does not know which services to inject. To prevent this, the injected services need to be specified as strings before the actual controller function. You can also inject dependencies the following way, as recommended here:
angular .module('myApp') .controller('MainController', MainController); MainController.$inject = ['$scope']; function MainController($scope) { ... }
But you can actually avoid this altogether if you are using ng-annotate (you might also see ngmin but it’s deprecated) – which can be very useful if you are working on a large, complex project where a controller can easily have 20-30 injected dependencies.
There are many examples like this in AngularJS, where things often depend on personal preference. It might be daunting at times to see so many variations across projects – which is the right way to do things both in terms of style and design patterns? Which JavaScript style is more common? Which project structure is considered to be the most effective? Which front end helper tools are absolutely necessary and which don’t really add value to the project?
A good place to start, aside from the official tutorial and API docs, would be the book AngularJS Up and Running by Shyam Seshadri and Brad Green. You do not have to follow all its recommendations, but it explains various AngularJS components in a nice, detailed way and provides good insight into AngularJS development practices.
Well, the truth is, there’s no universal right way. So how would you decide which is the best practice? The best way is to just start developing and take note of which way is more comfortable for you and/or suits your project needs the best. Doing some research on various existing AngularJS projects will help. It’s also important to pick certain standard or practice, both for AngularJS and JavaScript, and follow it across the project to keep the code clean and consistent. Even seemingly small things, like indentation and variable names, count a lot.