If you were to search the internet for Angular best practices, you’d find a lot of resources. I found myself constantly searching for a multitude of things when I first started using Angular. While most of them worked, I kept looking at the code and thinking to myself, "There has to be a better way to do things," and, "What are other people doing?"
Through these searches, I found community leaders such as Todd Motto and John Papa and learned some lessons from them, as well as some lessons from my own experiences.
The goal of this synopsis is to empower those of you just starting with Angular and enable you to write clean, easy-to-maintain code without overwhelming you.
When starting a new application using Angular, it’s recommended to put all of the files related to the Angular application into their own folder. When creating our document structure, we should adhere to the LIFT principle:
- Locate your code quickly.
- Identify the code.
- Flat file structure.
- Try to stay DRY (Don’t Repeat Yourself).
Notice that by structuring the documents in our application like this, it becomes easy to find what we need. If the application gets larger, it may make sense to add another folder in the root that we might title “Pages” and then place our code for each route into its own folder from there, such as Pages > Home and Pages > Edit. This keeps our tree relatively flat and makes things easier to find as the amount of code increases.
It wasn’t until I came across John Papa’s style guide that I learned about the $inject service. At first, I didn’t see the benefit. The way I just mentioned worked, so why change it?
The reason for making the change comes down to readability. By using the $inject service, we can see how our controller becomes easier to understand for anyone who might look at our code. And it’s still safe to minify.
Notice that the code looks much cleaner. We aren’t indented as much as the first method to minify our source code. It’s also much easier to ensure everything we need to inject is available, which can be hard to see using the first method as we have more dependencies.
Public members up top
This makes it easy at first glance to see what is usable in that section of code. If we also alphabetize the functions as we go down the page, it becomes very simple to find our code when we need to make changes to it.
Here’s an example of what not to do:
This code would work, but it could make it difficult to determine what should occur during the page load and what functions can be called from the DOM. If we structure our code as exampled below, it becomes easier to follow.
Here’s an example of a service that follows the same guidelines and also stays DRY:
Notice that by putting our return statement at the top, we can easily tell which functions are available for the controllers to call. It also alphabetizes the methods in the service, making them easier to find as the code is expanded.
Separation of concerns
Starting with the basics, remember this is still an application that’s being developed and, thus, we should adhere to separation of concerns. Our controller should only be responsible for updating our DOM data. Therefore, any data that needs to be retrieved should be a call to one of our data services.
If any other data needs to be saved into session storage or a cookie, this should also be handled in a data service as it doesn’t affect the DOM. If we’re using directives, each directive should have its own file. If the directive needs data from our server, the directive should have its data passed to it by the controller that retrieves the data from our data service.
Business logic to services
Anything that has logic tied to it should be delegated to a service and not in a controller. The reason for this is to keep our code DRY. Rather than implement the same logic in multiple places, let the service handle it.
An example of when to do this is when looking up a variation ID of a product based on the color and size the user selected, as they all had the same source product ID. Rather than let the controller handle this logic, I separated it off to my product service and allowed the service to return the variation ID. This allowed the multiple controllers that relied on this logic to only be responsible for updating the data used in the DOM.
This article originally appeared on June 29, 2015.