Angular Anti-Patterns




BugReplay Guest Blog Written by Tristan Jesse

=

Angular Anti-Patterns

I've been developing with Angular for the better part of a year now and along the way I've come across some common anti-patterns that can really hamper progress as your application scales. There are all sorts of anti-patterns, which I could go on for days about, but here I'll be talking about file structure, naming conventions, and logical structure. For newer developers, even skilled ones from time to time, falling into programming anti-patterns is easy and common.

What every developer should aim for is to follow design patterns (generally agreed upon as good practice) as much as they can to complete their task. If you aren't following good design patterns, then more often than not down the line you will run into bugs you can't track down, spaghetti code, and bloated components or modules giving you headaches. With Angular, there are quite a few rules and recommendations to be followed that will make your code easier to read, review and reuse down the line.

Structure and Single Responsibility

No matter the size of the app it is important to consider the file structure from the start. Even with a small scale app being able to navigate through your structure quickly will make life easier for you. Keep this in mind from the beginning but also be aware of the direction your app will be taking in the future. So let's take it from the top with a freshly generated project.

If you open up your `app.component.ts` file you'll find that you can get just about everything accomplished just within this file. I've just pulled this example straight from the Angular docs.

```typescript
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component, OnInit } from '@angular/core';

class Hero {
  id: number;
  name: string;
}

@Component({
  selector: 'my-app',
  template: `
      <h1>{{title}}</h1>
      <pre>{{heroes | json}}</pre>
    `,
  styleUrls: ['app/app.component.css']
})
class AppComponent implements OnInit {
  title = 'Tour of Heroes';

  heroes: Hero[] = [];

  ngOnInit() {
    getHeroes().then(heroes => this.heroes = heroes);
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ AppComponent ],
  exports: [ AppComponent ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule);

const HEROES: Hero[] = [
  {id: 1, name: 'Bombasto'},
  {id: 2, name: 'Tornado'},
  {id: 3, name: 'Magneta'},
];

function getHeroes(): Promise<Hero[]> {
  return Promise.resolve(HEROES); // TODO: get hero data from the server;
}
```

This is a fairly simple app but already just looking at this file gives me anxiety! Coding like this does not follow the single responsibility principle, so if you ever come back to this project you will have a hard time figuring out what each file's function is. Just take a look at everything going on in here: a model is declared, our app component is declared and bootstrapped, we've got our `NgModule` defined, there's a bit of mock data declared and a function is created to eventually fetch data. Anyone that comes across this after you (including you) will hate trying to decipher all of this.

These can easily be split up into several files that make things clear and concise down the line. When creating new files try to keep things organized in folders with relevant names; keeping models together or keeping services together for example. It's a good idea to keep things as flat as possible but not let that get out of hand. If you find yourself with more than 7 files in one folder it might be time to consider adding in another folder for clarity.

Naming Conventions

While following a consistent naming scheme may not seem that important (or that exciting), it can have a big impact on readability and understandability in the future. If you've been coding for awhile, many of the conventions you should already be following will apply to Angular as well but there are also some new items to take into account. With Angular, there are several different types of files and we should be consistent with their naming schema. The Angular CLI will help you with this as well as you generate new files for you project.

In an Angular project there may be services, components, guards, directives and a few other types of files. When naming a file it's best to have a descriptive name of the feature, then the type of file, followed by the extension: `feature.type.extension`. So if I wanted to create a user service, a proper filename for typescript would be `user.service.ts`. When using the Angular CLI command of `ng g service user` this will automatically generate a `user` folder and files with this naming convention followed. It's always simpler to use the CLI to help you create your files to help with structure and naming.

Deciding on the descriptive name would often trip me up however. Again I would want to create a user service but I use the command `ng g service user-service` thinking that is the best description. What is generated here however ends up looking quite sloppy. I end up with a filename `user-service.service.ts` and here is the generated code:

```typescript
import { Injectable } from '@angular/core';

@Injectable()
export class UserServiceService {

  constructor() { }

}
```

Remember when generating files with the CLI that it will automatically append the type of file it is which means you do not need to put that information in the description.

Placing your Logic

Occasionally I've found myself building my front end and wanting to do some math on one of my variables. Take a look at this next code block, and decide if there are any anti-patterns here:

```typescript
@Component({
  selector: 'toh-hero-list',
  template: `
    <section>
      Our list of heroes:
      <hero-profile *ngFor="let hero of heroes" [hero]="hero">
      </hero-profile>
      Total powers: {{totalPowers}}<br>
      Average power: {{totalPowers / heroes.length}}
    </section>
  `
})
export class HeroListComponent {
  heroes: Hero[];
  totalPowers: number;
}
```

There's just a simple division in there for `Average Power` but this really isn't the place for it. The proper way is to define a new variable in the component class that will do the division and then call that variable in the HTML. Keeping the logic out of the view and inside functions will make your code easier to test and reuse down the line.

With this example we can also touch back on structure. With you HTML it is easy to keep it in a component class but as the HTML gets more complex it becomes a bit harder to read and maintain. It's easy to extract the HTML template into it's own file (remembering your naming conventions) in order to clean up your component class.

```typescript
@Component({
  selector: 'toh-hero-list',
  templateUrl: './hero-list.component.html'
})
export class HeroListComponent {
  heroes: Hero[];
  totalPowers: number;

  get avgPower() {
    return this.totalPowers / this.heroes.length;
  }
}
```

Wrapping Things Up

In the grand scope why does all this really matter and what can you do to write good code? As developers, we should each strive to deliver quality code that we can hang our hats on. It is hard to anticipate where the lifecycle of your code will go, and avoiding anti-patterns will make it easier to work with your project for years to come. Code that works for demonstration purposes might not be the best as your application grows. Keeping the scale of the project in mind from the start will save you hours of trouble down the line. If you are looking for more guidance on proper Angular design patterns, the Angular Style Guide has plenty of more information.

Protractor and Headless Chrome


BugReplay Guest Blog Written by Matthew Lilley
=
Following our previous article Up and Running with Headless Chrome, this article will briefly explore both Protractor and Headless Chrome, what they are, and when and why you should use them. Next, we’ll put them to practice by testing a simple Angular 4 application, end-to-end, with Protractor, which will use Headless Chrome.

First, what’s Protractor? From the Protractor site: “Protractor is an end-to-end test framework for Angular and AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.”

It’s used to simulate actions you expect users to take within your application, and test the outcomes against your expected outcomes.

And Headless Chrome? To put it simply, it’s a reference to using Google Chrome with Headless Mode enabled. Headless Mode allows Chrome to run without a graphical user interface (GUI), so it doesn’t need to render the browser for humans.

But Why? In a word, performance.

For a small application, you might not initially see the benefit of using Headless Chrome with Protractor, but as your application grows, and you amass a large collection of complex tests, performance can quickly become a factor. Waiting around for your tests to finish isn’t fun, and as always, time is money.

Want to know more? If you haven’t already, you should check out our previous article Up and Running with Headless Chrome, which is a thorough write up of using Headless Chrome natively, and with various 1st and 3rd party libraries.

Let's get started:

There are a few requirements that are needed to complete this tutorial.

Requirements

NodeJS (nodejs.org)
Angular CLI (cli.angular.io)
Protractor (protractortest.org)

Now that you’ve installed the requirements, we can get started by creating a new Angular application using the Angular CLI. Open up your terminal of choice and run:

ng new protractor-headless

This will create a new Angular project in a folder called protractor-headless. Let’s enter this folder:

cd protractor-headless

And lastly serve the app:

ng serve

Navigate to http://localhost:4200/, you should see your app.

For the purpose of this tutorial, the Angular CLI starting project is perfect, as it comes with a simple spec for the landing page that can be found in /src/app/app.component.spec.

So let’s try it out…

For this to work correctly we need to ensure firstly that both the application is being served at http://localhost:4200/, and we have a selenium web server is running. We already know our app is being served, so let's start a selenium server. Open up another terminal window and run:

webdriver-manager update && webdriver-manager start

In case you’re wondering where webdriver-manager came from, it’s installed as part of the Angular CLI. Here we’re simply updating the webdriver manager, and starting it.

Now that we know that the app is being served and a selenium server is running, we can start out test suite. Open up another terminal in the app root directory (protractor-headless), and run:

protractor protractor.conf.js

You’ll see the Chrome GUI briefly and close, and you’ll then see in your terminal “Executed 1 of 1 spec SUCCESS”.

So we know our test passed. But we clearly aren’t using Headless Chrome, as we saw the Chrome GUI briefly. We need to make Protractor use Chrome with Headless Mode enabled.

Open up the protractor.conf.js, you’ll see:

capabilities: {
 'browserName': 'chrome'
},

We’re going to modify it to:

capabilities: {
 browserName: 'chrome',
 chromeOptions: {
    args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
  }
},

And we’ll rerun the test suite:

protractor protractor.conf.js

Again, you’ll see in your terminal “Executed 1 of 1 spec SUCCESS”. But notice you didn’t see the Chrome GUI briefly like before? That’s our confirmation that we’re indeed using Chrome with Headless Mode enabled.

It’s really that easy!

BGP: The Arthritic Backbone of the Internet

February 2014 was a cold month for Tokyo residents, In the bustling suburb of Shibuya, the Mt. Gox bitcoin exchange felt the chill most acut...