AngularJS Best Practices: I’ve Been Doing It Wrong! Part 3 of 3
Three sanity-preserving ideas that will make me and you 10x more productive with real-world AngularJS applications
This is the last in a three-part series on practical large-scale development with AngularJS. The TL;DR version is at the end of the article. If you have not read the first two parts (part 1, part 2), you might want to start with them. They lay out the foundation for the structure of a large-scale AngularJS project, and automatic testing with AngularJS and ng-boilerplate project template. In this part, I’ll list the common pitfalls to be avoided, best practices to be followed, and specific areas that need our attention as we transition from years of jQuery development into our first well-designed and well-tested large-scale Angular projects.
Quit jQuery for a While
To teach your brain the habits of an AngularJS superhero, you need to free your mind from the reflexes ingrained in you after years of jQuery practice.
I’ve highlighted some parts of Angular that may be unexpected to a jQuery-trained brain in an earlier post, AngularJS for jQuery Developers. The best way to get free from jQuery reflexes in Angular projects is to avoid using jQuery completely, at least until you master the new way.
In jQuery, DOM is the center of developer’s attention. You start with designing the web page, you manipulate DOM with jQuery, you even store the state associated with DOM in DOM. So in jQuery world, DOM is both your model and view. This becomes unnecessary when you have two-way data binding and a magical way to create new tags and attributes with AngularJS directives. With AngularJS, you are a wizard who can augment HTML, the very language of the web.
So, don’t start your app development with DOM or visual design. Instead, begin with application architecture. After you’ve decided what is it that your app does, and what data structures you’ll need for this, what logical parts will become controllers, you can design the views based on that.
Scopes are Important
Scopes are the meat-and-potatoes of AngularJS, so it’s a good idea to become really comfortable with them – know when scopes are created and destroyed, how inheritance and data exchange works between them, and how re-evaluation process works. There’s an excellent article on scopes at “The Nitty Gritty“, go read it please. Here’s a brief summary of scope-related advice from the article:
- Do not use [expensive] functions in expressions (in templates) – they are re-evaluated often
- Use $scope.$apply() when applying external data changes (e.g. callback from outside AngularJS)
- Never store references to DOM elements in the scope
- Do not access the DOM outside of a directive
- Be aware of the parent-child relationships between scopes and their data.
Equivalents of Familiar Functions
Replace window.setTimeout with $timeout, $.ajax with $http (or better yet, use resources and models), and get familiar with $q promises. All these things play nicely with Angular evaluation loop, and you do not have to worry about calling $digest or $apply manually.
Check out the global APIs in Angular documentation – it has a rich set of utility functions that you need on a daily basis. Here are a few:
While I was writing this triad of articles, Josh David Miller has released version 0.2 of his awesome boilerplate. (I am not affiliated with it in any way, I just think it’s a collection of really good ideas, all in one place.) In addition to providing best practices for structuring your code and automating tests, it also integrates a few companion libraries that really add power to an AngularJS project.
The tools from AngularUI team may even cure you from homesickness for jQuery plugins and jQueryUI. It seems to be working for me.
Here are some of the companion libraries that are worth getting intimate with.
- AngularUI-Bootstrap – Twitter Bootstrap components written in AngularJS (included with ng-boilerplate)
- AngularUI-Utils is a bunch of essential utilities (included with ng-boilerplate)
- AngularUI – ports of many jQueryUI components
- UI-Router will probably become a part of AngularJS core in the near future. You’ll want it if your application uses a nested navigation structure.
- Restangular – a great way to simplify your JSON CRUD code.
Read Good Code
In addition to the libraries mentioned above, I will borrow, steal and plagiarize shamelessly (but respectfully and without breaking the law) from well-written projects. I encourage you to do the same. Let’s learn from smart people.
- Angular-app, which I already mentioned – use it for examples of tests and client-server interaction
- Built with AngularJS – holy smokes, a whole collection of good real-life projects, approved by AngularJS creators! You can’t beat that.
The AngularJS community seems to be growing very rapidly, and the culture is just unbelievable. People contribute open-source libraries, write documentation, share tricks and answer questions. It feels great to be a part of the AngularJS world.
TL;DR (but really, read the whole three articles – it’s worth it)
- Use ng-boilerplate as a template for your projects.
- Learn to use unit-testing and end-to-end testing with Angular, and make it your religion. Use testacular/karma and Jasmine. It will save you months and years of development. Use end-to-end tests in addition to unit tests. Borrow test practices from good AngularJS applications.
- Acquire new Angular habits, and avoid old habits that do not translate into AngularJS world.
- Know how scopes work
- Learn to use templates, directives and filters instead of DOM manipulation
- Know Angular equivalents of common jQuery functions
- Use AngularUI and related libraries by the same team
- Read good applications sources (https://github.com/angular-app/angular-app/, http://builtwith.angularjs.org/).