Getting Intimate with Angular and TypeScript

If you are like me and have a background of using AngularJS, making the move to Angular may have come with some resistance. What I find to be the biggest difference of the two, and my biggest impedance, is Angular’s use of TypeScript. They have married themselves to TypeScript so strongly I do not even know where Angular ends and TypeScript begins. Another source of my contention is handling the responsibility compiling and module loading that comes with TypeScript. I had been avoiding TypeScript and consequently Angular because I did not want this responsibility. For once in my life, can I be lazy?

I am not a part of the camp that thinks we should be using the latest and greatest technology. Rather, my philosophy is to use the best tool to get the job done. Then it dawned on me, how can I use the best tool if I do not know what tools are available along with their advantages and disadvantages? Hence, I did need to take time to understand Angular and TypeScript. The knowledge would make me a much more powerful developer. Which reminds me of Goku's advice to Gohan on becoming a Super Saiyan — "Power comes in response to a need, not a desire." For anyone looking to increase their power level quickly and painlessly, I explain the key parts of Angular to get you started, which are TypeScript classes, modules, and decorators.

TypeScript Setup

Before we get started, I need to define the terms AngularJS and Angular because they go by many names. AngularJS is version 1.x of the framework (also known as Angular 1). Angular is version 2.x. and greater (also known as Angular 2 or Angular 4). They are essentially two different products, and that is probably why they have their own websites. At first, I did not like feeling coerced into using TypeScript. Angular says you do not have to use TypeScript. However, all of their documentation uses TypeScript, so I am not presented with much of a choice. I prefer to be the one who is opinionated — not my tech. However, I will let this one slide because without TypeScript I would not consider it Angular and using TypeScript is a positive. You can read about the benefits in this post written by Joseph Rex.

If you are new to TypeScript, I recommend testing it out on its own so you can appreciate it outside of Angular. To get started with TypeScript, you will need to download its command line tool for compiling the code. Because browsers do not use TypeScript natively, it needs to be compiled to JavaScript. This is also known as transpiling — compiling a language from one form to another. You can install the CLI using npm. You can install Node and npm from https://nodejs.org. Inside of your project folder, create a package.json file with the command npm init. Then, install TypeScript globally and locally:

$ npm install -g typescript
$ npm install --save-dev typescript

Create a file named helloWorld.ts and inside add the statement console.log("Hello, World"). You can write any JavaScript code in your file and TypeScript will understand it. The important thing to remember is to use the file extension ts. Next, compile the file:

$ tsc helloWorld.ts

This creates another file called helloWorld.js inside our directory. For now, the contents of our file have not changed because we did not use any TypeScript specific syntax. To execute the code we wrote, run the command node helloWorld.js.

Classes

In Angular, classes are the building blocks of our app. It is how we create our services, components, and other features. This is the general form for defining a class:

class ClassName {
	attr: type;
	constructor(arg: type){
		this.attr = arg;
	}
	methodName() {...}
	methodName() {...}
}

The constructor is a special function that lets us pass data to our objects when they are instantiated. This includes services and other injectables. By default the attributes and methods of a class are public, meaning they can be accessed by code outside of the class. They can also be private (cannot be accessed outside of the class) and protected (derived methods of the class have access). In addition to values having types, methods have types as well. If the method returns nothing, its return type is void. Specifying a method's type is optional.

This is our Hello World example altered to use class syntax:

class HelloWorld {
	name: string;
	constructor(name: string){
		this.name = name;
	}
	greet(): void {
		console.log(`Hello, ${this.name}`);
	}
}

let greeting = new HelloWorld("Alberta");
greeting.greet();

Compile your code again to see the changes. It will print "Hello, Alberta".

Modules

TypeScript modules provide a means to organize related code and provide an interface for other parts of your program to use this code. It is worth noting that an Angular module is not the same as a TypeScript module. An Angular module refers to a class that is responsible for tying together related files. Code you want to make available for use in the module has to be exported. The syntax looks like this:

//myModule.ts

export const foo = 'foo';
export class Bar { }
export function baz(){ }

When we want to use this code, we have to import it into our file. Example:

//main.ts

import { foo, Bar, baz } from 'path/to/myModule'

Let us revisit our hello world example. Instead of instantiating our class inside the same file as our class, we can export the class and use it in another file. Create a file named main.ts with the following:

import { HelloWorld } from './helloWorld';

let greeting = new HelloWorld("Alberta");
greeting.greet();

Since we have multiple files, we can compile them with the command tsc -p path/to/tsconfig.json. Add the file tsconfig.json to your project and add the following inside:

{
  "compilerOptions": {
    "target": "es5",
    "sourceMap": true,
    "experimentalDecorators": true,
  }
}

Compile your code:

$ tsc -p ./

Because we are using modules in our project, we need a module loader. Angular uses SystemJS in their quick start project. There are other module loaders you could use, for example Webpack. We will create a new project using the Angular quickstart project. I like this because it has everything we need for building our app already set up. I experimented with creating my own build using Webpack. It was great for learning, but in the end, I felt it was not worth the effort. Angular did a great job already. I will not get into the details of what is in the build or how it works here. However, if you are interested in seeing an article on that topic, let me know in the comments.

These are instructions for installing the quick start project:

git clone https://github.com/angular/quickstart.git
cd quickstart
npm install
npm start

This will open a browser window at the address localhost:3000 that displays Hello Angular. Next, let us delete the non-essential files.

OSX:

xargs rm -rf < non-essential-files.osx.txt
rm src/app/*.spec*.ts
rm non-essential-files.osx.txt

Windows:

for /f %i in (non-essential-files.txt) do del %i /F /S /Q
rd .git /s /q
rd e2e /s /q

Now you have the basic files you need to start building an Angular app.

Decorators

A decorator is a design pattern used to add features to a class. TypeScript uses the general form @expression to add a decorator to a class. In Angular, decorators are used to specify the type of class and the metadata associated with it. A component is a class with the @Component decorator. Components act as the controller and the view. Let's modify app.component.ts to look like this:

import { Component } from '@angular/core';

@Component({
	selector: 'my-app',
	templateUrl: './app.component.html',
})
export class AppComponent {
	name: string;
	constructor(name: string){
		this.name = name;
	}
	greet() {
		return `Hello, ${this.name}`;
	}
}

The selector option in the decorator is the tag name for our view injection. In index.html it looks like this:

<body>
  <my-app></my-app>
</body>

The templateUrl is the path to our view. Create the file app.component.html and add the following to it:

<h1>Hello, {{ name }}</h1>

name refers to the property we set in our AppComponent class.

A module is a class the the @NgModule decorator. This is what app.module.ts looks like:

import { NgModule }     		from '@angular/core';
import { BrowserModule }		from '@angular/platform-browser';

import { AppComponent }  		from './app.component';

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

Inside the decorator, imports are a list of angular and 3rd party library dependencies. The declarations are the view classes that belong to the module. Moreover, bootstrap is the main application view. Bootstrap should only be set by the root module.

The main.ts file will be used to launch our app. Example:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

The module, component, html template, and main file are the basics you need to build a project.

Conclusion

TypeScript is a fundamental feature of Angular that provides more than just types, it provides the structure of the framework. Modules are how we organize an app. Classes let us create the different objects of our app. And decorators are added to classes to declare what kind of Angular object it represents. Another useful feature of Angular is their cli. Development with Angular can be significantly sped up using their quick start project.

If you are considering migrating a codebase from AngularJS to Angular, you should consider the pros and cons of switching to Angular. Have you worked on an AngularJS project that was upgraded to Angular? If so, what prompted your team to make the change? If you used Angular for a completely new project, what benefits did it give you over other frameworks? Share your thoughts in the comments.

Resources