Yet Another Opinionated AngularJS Best Practices Guide

A couple of months ago, I created an Angular Best Practices guide for the team I was on at the time. The ideas for those Best Practices came from several places: blog posts, Github repos, personal experience, ideas from others on the team, etc (in other words, I’m not claiming credit for the ideas below. They’ve come from various places, people/coworkers I respect, with some personal opinions added). Now that I’ve started a new role, I wanted to update my Best Practices guide. The original version was just a Google doc, which I then imported into a Word doc. But, I had thoughts of adding it to my Github account in case others were interested. Then, a few weeks ago, Todd Motto posted his Angular Styleguide. While it contained some of the same ideas from my original document, Todd also had many more that I hadn’t thought of, but really liked. My document was also very light on code samples/examples, which was something I wanted to fix. When I saw that Todd moved his Styleguide to a Github repo, I thought I would just fork it instead of starting my over. I liked the organization and formatting of his doc, so it made sense to start from there.

I spent a few hours working on my tweaks to his Guide, and finished it up over the weekend. So my fork of his guide is missing a few things from Todd’s, and contains many more that I’ve added. I know some of my additions are personal preferences, but I added them because I think they can provide consistency in how projects are structured (especially the stuff in the Files category).

I haven’t decided yet whether to commit any of my changes back to his repo. I thought I would post them first in my fork and get some community feedback.

You can view my fork of the styleguide (which I am calling Best Practices) at my Github repo: AngularJS Best Practices Guide. I also hope to create another repo containing an Angular starter project (another Github repo) that follow these guidelines. That way you can see what these guidelines look like when applied to a simple project.

I’ll list some of the additions I made below, but you’ll need to visit the repo to see further explanations and code samples:


  • When possible, use angular.element(), etc. instead of jQuery lookups and DOM manipulation.
  • Don’t wrap element inside of $(). All AngularJS elements are already jqobjects.
  • Do not pollute your $scope. Only add functions and variables that are being used in the templates.
  • Do not use $ prefix for the names of variables, properties and methods. This prefix is reserved for AngularJS usage.
  • Use ng-bind or ng-cloak instead of simple {{ }} to prevent a FOUC (Flash of Unrendered Content).
  • When you need to set the src of an image dynamically use ng-src instead of src with {{}}.
  • When you need to set the href of an anchor tag dynamically use ng-href instead of href with {{}}


  • One module per file
  • Each file should get its own namespace
  • Each filename should match the controller/service/etc name
  • Function name and file name should match
  • Each file should be CommonJS compatible
  • A specific directory structure


  • controllerAs ‘self’


  • Templating (avoid inline templates)
  • Each directive should live in its own directory
  • Use isolate scope in directives whenever possible

Routing Resolves

  • Promises (modified Todd’s entry to recommend ui-router, $stateProvider, etc)

10 thoughts on “Yet Another Opinionated AngularJS Best Practices Guide

    • There are times where the page can be rendered before Angular has linked the model to the view (I believe that is the right way to phrase that). In other words, say you have the following in your html: {{}}. There is the chance your users could see {{}} flash on the screen right before Angular has a change to evaluate (hence the term Flash of Unrendered Content). If you use ng-bind or ng-clock, the span would not be rendered until Angular had evaluated the expression.

      Liked by 1 person

    • Wont work when page has problems loading content or files. Also: with your main div you should use class=”ng-cloak” instead of just ng-cloak as that might not be ready yet


  1. Pingback: Angular Best Practices Seed/Template | Jeff Cunningham

  2. This was a great read! In the routing resolves section, how do you typically handle or tell the user when the routing promise is rejected?


  3. Great read thanks! In the routing resolve section, how do you handle when a route is rejected?

    Also, what if the promise takes a while to resolve, what’s a good strategy to let the user know it’s waiting, since the controller/view won’t be loaded until the promise is resolved?


    • First…glad you enjoyed the post & guide.

      Rejected Route: Good question. My first thought is to have the rootScope emit an event with the description of the error/failure. I would also have a directive that’s sole purpose was to listen for the event emitted by the failed resolve and display the message to the user. This sounds like a good idea for a blog post, actually, so I’ll try to show my answer using real code…look for a post in the next day or two.

      User notificiation: Actually, in the best practices seed project I mentioned on the blog yesterday, I handle this situation using angular-loading-bar from chieffancypants. It is configured in the app.js file, and anytime a http request takes more than 1 second (this is configurable), the user will see a loading bar to let them know the app is working.


        • While working on the app messaging example I mentioned this morning, I noticed that I had a bug in the angular-loading-bar config (which prevented the loading bar from showing). This will be fixed shortly.

          Also, I have the message code working (for displaying an error msg when the promise is rejected) and added it to the angularBPSeed project. I’ll commit that code later today, and add a quick blog post to explain the solution 🙂


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s