Angular Best Practices: The Rule Of 1

Angular Best Practices: The Rule Of 1

 

Angular 1.x has been around over several years now and since it’s become one of the most popular frameworks out there, you might be wondering if any best practices have evolved over time. If you are considering developing your first angular application and what to know what the potential pitfalls would be but unsure where to look, we plan to tackle some of those. In this series, we are going to cover the best practices when developing your angularjs applications. We’ll take from various popular style guides and in this article, we will start with John Papa’s.

When developing angular apps, we define controllers, templates, routers, directives and components. While it’s possible to put all of your js logic inside one file and bundle all of it together, you are actually making it more difficult to maintain and read over the long run. Think about the evolution of your project. At first it is probably a simple and concise app but over time as more logic and complexity is introduced, your files becomes extremely large and bundle all sorts of app logic inside one location. Plus, if you are working in a team environment, you are probably dealing with tons of merge issues (think github). Not only are you having all of this fun stuff going on but you are actually increasing the potential for collisions when making commits to your repo with fellow developers. Additionally, by coupling all of these different angular artifacts into a single file, you may be potentially coupling unnecessarily dependencies with shared variables, injections and so on. And Finally, there’s the difficulty of unit testing your angular artifacts.

How do we solve this?

Rule of 1

  • Define 1 component per file, recommended to be less than 400 lines of code.
  • Why?: One component per file promotes easier unit testing and mocking.
  • Why?: One component per file makes it far easier to read, maintain, and avoid collisions with teams in source control.
  • Why?: One component per file avoids hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or unwanted coupling with dependencies

Let’s take a look at an example of applying the Rule of 1.  

In this application, notice how all the logic is contained inside a single js file. We have coupled our controllers, services and directives into a single location.

Example:

We start by applying the rule with separating our bundled “components’ into single separated components.

Doing this would imply the following folder and file structure structure:

/todo

 

  •       todo.controller.js
  •       todo.directive.js
  •       todo.services.js
  •       todo.module.js

 

Notice in this example it’s clear by simply looking at the name of what the purpose of each individual file is for. Notice the name prefix. Just by reading the name “todo.controller.js”, you get the idea that you are dealing with a controller for a todo module.

Next, we split out definitions in each of these files and use dependency injection to link them together.

First, we define our module:

Next, we define our controller method in its own file:

Finally, we define our services into a separate file

To demonstrate the flexibility of this approach, let’s introduce a new problem. Suppose a new feature is being developed called Memo’s. One of the features is to display the todo services data in a different visual representation.

Because we have separated the files out, we can leverage dependency injection to handle wiring our dependency externally (in separate files) by simply using dependency injection (DI). Now, we make the service available to our new feature by including it:

Now, suppose that the underlying service contract is being changed by adding a new additional field and that we want to be able to categorize our todo’s but still support our legacy systems using the existing todo’s implementation.

We can modify our backend service to return a new field ‘category’ which bubbles up to the UI layer.  Our newly updated MemoCtrl will observe the property and act accordingly, yet all the consumers of the existing application will go unaffected by the its introduction.

We now have multiple controllers using the same underlying services but have a clean separation of concern. This meant that we only had to modify one file while all of the existing service consumers did not need to be changed. If all the logic was developed in a single file, we would have had to create duplicate services or implement a shared service to handle these different features instead of using a dependency injection to handle this for us.

Benefits:

 

  • By using the rule of 1, each individual file represents a single functional component or unit which when assembled together creates our application.
  • By using the rule of 1, it’s clear what each file’s purpose is and what the intent of it is.
  • By using the rule of 1, our applications components are more flexible and allow for more change.
  • By using the rule of 1, three team members could be working simultaneously on three different files without having to deal with merges. One for the memo feature, one for the todo feature and one backend developer for the service.

 

Note that in this example no one is working on the actual TodoSrv angular factory and yet it handles it automatically!!

To learn more about all sorts of things we like to talk about, check out our upcoming workshops.

To view or add a comment, sign in

More articles by Michael Vargas

  • AWS Step Functions Part V

    We've put together the workflow to support an on-boarding badge process. In this article, we're going to tweak the…

  • AWS Step Functions Part IV

    We've put together the foundation for our workflow. In this article, we're ready to integrate all the different moving…

  • Workflow Series III: AWS Step Functions

    Hey there! We're working on putting together a workflow that implements a distributed processes. A process that could…

  • Workflow Series II: Creating A Simple Workflow With DynamoDB Streams

    Before we begin, check out the previous article here to give some background. We're working on developing a workflow.

  • Workflow Series: AWS Step Functions

    A workflow consists of an orchestrated and repeatable pattern which can resemble or model a business or technical…

  • The Serverless Framework

    What's Serverless? The Serverless Framework is a free and open-source web framework written using Node.js.

  • Writing Asynchronous Lambda Functions

    Thanks to the introduction of NodeJS 8.10 runtime environments, it's now possible to create asynchronous AWS Lambda…

  • ES8 Features: Async/Await

    The asynchronous function was developed to solve the problem of dealing with promises and callback h, e, double hockey…

    2 Comments
  • What is Serverless Architecture anyways?

    This article is about the fundamentals to decide if it's something you want to consider. I promise to not write about…

  • Unit Testing AWS Lambda Functions

    Background: In my previous article, we defined an interface that communicates to our database. This could be specific…

Others also viewed

Explore content categories