There’s no denying that the Angular framework is becoming more and more pervasive in today’s programming culture. According to JavaScript, Angular has been used to develop high-traffic websites, including those from NBC, Walgreens, Intel, Sprint, ABC News, and thousands of others.
The framework’s popularity not only stems from its Google pedigree, but also because it’s easy to learn and has a vibrant community that you can leverage for assistance when you run into problems. Yet, while Angular is known for its simplicity and intuitive design, there are some core tenets that programmers should keep sacred when working with this framework.
Write singularly responsible Angular components. Follow the “Rule of 1” principle, which states you should define one component per file, recommended to be less than 400 lines of code. One component per file makes your code far easier to read and maintain, and to avoid collisions with teams using a source-control solution like Git or Mercurial. It also helps to avoid hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or form unwanted coupling with dependencies.
Use a consistent naming convention for your Angular components. Use consistent names for all components following a pattern that describes the component’s feature and then (optionally) its type. A recommended pattern for you to follow is feature.type.js.
There are two names for most assets: the file name (checkout.controller.js), and the registered component name with Angular (CheckoutController).
There’s a running joke in the industry that there are only two hard things in software development: cache invalidation, and naming things. Naming conventions help provide a consistent way to find content at a glance. Consistency goes a long way to help your project, team and company provide tremendous efficiency.
Wrap Angular components in an Immediately Invoked Function Expression (IIFE). Now that we’ve talked about keeping Angular components in separate files, let’s talk a little bit about how those files should be laid out. Wrap the entire file in an IIFE. This ensures that variable and function declarations do not live longer than expected in the global scope, which helps to avoid naming collisions with other libraries. It also allows you to utilize the “use strict” declaration without affecting third-party components that may not utilize “use strict”.
Keep data calls in a factory, not in the controller. You should keep logic for making data operations and interacting with data in a data service, contained in an Angular factory rather than in an Angular controller. Make data services responsible for XHR calls, local storage, stashing in memory, or any other data operation you can think of, and inject those into your Angular controller.
The controller’s responsibility is for the presentation and gathering information to/from your HTML. It should not care how it gets the data, just that it knows whom to ask for it. This will not only simplify the code in your controllers, but also make it easier to unit-test your controllers by being able to pass in a mock data service, which is simpler than mocking the $http service.
Write minification-safe Angular components. Minification is the act of compressing client code delivered by a server so that the file size is lower. If you have a lot of user load on your web application, this will help your server handle more requests with fewer resources. For Angular code to be correctly minified, avoid using the shortcut syntax of declaring dependencies without using a minification-safe approach like this:
Instead, you should manually identify dependencies using $inject. This is the most readable way to manually declare dependencies for an Angular component:
Stop using $scope; use the Controller-as syntax. Controllers are constructed or “instantiated” when they are needed, and deconstructed or “deinstantiated” when they are no longer needed. The Controller-as syntax is closer to that of a JavaScript constructor than the classic method of injecting a redundant $scope service into your controller. It also promotes the use of binding to a “dotted” object in the View, which brings a greater sense of context, is easier to read, and avoids any and all scope inheritance issues that you may run into in the future.
Modularize your Angular code. Modular applications make it easy to plug and go as they allow development teams to build vertical slices of the applications and roll out incrementally. This means we can plug in new features as we develop them. Some tips for creating modular Angular code:
- Create small modules that encapsulate one responsibility.
- Create modules that represent feature areas, such as layout, reusable and shared services, dashboards, and app-specific features (e.g. customers, admins and sales).
- Create modules that represent reusable application blocks for common services such as exception handling, logging, diagnostics, security and local data stashing.
- Create an application root module whose role is to pull together all of the modules and features of your application.
Use the client-side routing framework angular-ui-router. Client-side routing is important for single-page applications when creating a navigation flow between views and composing views that are made of many smaller templates and directives. UI Router offers all the features of the Angular router plus a few additional ones, including nested routing and states. If you’ve been using the Angular router, you should find that the syntax is quite similar and easy to migrate.
Keep your application organized
Software development expert John Papa encourages keeping your application organized using the LIFT principle, which consists of four basic guidelines. You should structure your app such that you can Locate your code quickly, Identify the code at a glance, keep the Flattest structure you can, and Try to stay DRY (Don’t Repeat Yourself).
Locate: If your team cannot find the files they need to work on quickly, they will not be able to work as efficiently as possible—and your structure needs to change.
Identify: When you look at a file, you should instantly know what it contains and represents.
Flat: Keep a flat folder structure as long as possible. When your folder structure is seven layers deep, it becomes difficult to work on a project. Think about menus on a website: Anything deeper than two should take serious consideration.
T-DRY (Try to stay DRY): Being DRY, or not creating files that have the same name, is important—but not crucial if it sacrifices the other LIFT principles. If you have many grid views in your application, prefix your templates with the name of the area of the application that the template is a part of.
Automate the writing of quality Angular code
Writing good Angular code does not necessarily imply that you have to remember how to write good Angular code all the time. The process is made easier by following a style guide that provides snippets you can use in your favorite text editor, and using a project generation framework such as Yeoman and the Hot Towel template provided by Papa in his Angular 1 style guide on his GitHub profile.