All the examples in this blog post are using TypeScript, since Angular 2 recommends to use it. We will try to keep this post as up to date as possible.

In order to get started please follow the quickstart example provided in the official angular docs, as it's up to date with all the things you need.

Building a Top-Level Component

Every Angular app has at least one root component, conventionally named AppComponent, that hosts the client user experience. Components are the basic building blocks of Angular applications. A component controls a portion of the screen — a view — through its associated template.

Import the Component Object

import { Component } from '@angular/core'

Angular 2 make use of the ES2015 module syntax (aka ES6). For those unfamiliar with the syntax, it makes use of import statements to access different pieces of code. In addition to these import statements, this syntax also relies upon export statements to make code accessible to the rest of our application.

When working with Angular 2, we will see these import statements being used to gain access to core features of the framework through different Angular 2 libraries. In the code block we just looked at, we see the import statement telling Angular that we want to access the Component decorator from the @angular/core library, which is one of the main libraries that this framework uses.

Some of the other APIs that are central to developing web applications in Angular 2.x. are:

Inside of each API you can find the following types to import from:

Add Meta-data to our Component using TypeScript Decorators

Once the Component object is imported, we can then begin describing our component using TypeScript's @ symbol. By checking out Angular 2's API guide, we can see that decorators are used to create new instances of @Directive, @Injectable, @RouterConfig and more.

Everytime Angular sees a decorator(@), it will know that we want to create a new instance of a component, and it will create our component according to our configuration meta-data.

We are able to configure the following options through our component's meta-data:

  • selector - defines the name of the HTML tag where this component will live. In this case, our component will by shown through the <my-app></my-app> tags.

  • providers - This is where we pass in any services that that want a component to access. If you want a global service, you wont pass it here, but in the Application's bootstrap. It will then be available throughout the all application, like the following example:

// main entry point
import { bootstrap }    from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';
import { BaseService } from './base.service'; // <- global service import
import { AppComponent } from './app.component';

bootstrap(AppComponent, [
	BaseService, // <- global service injection
	HTTP_PROVIDERS
])
.catch(err => console.error(err));
  • directives - We use the directive option when we want to access another component directive. Because this is the top-level component, we often see components being passed into this option.

  • styles - The styles option is used to style a specific component. One of the advantages of using components is their ability to encapsulate their styles. We could have just as easily linked to an external stylesheet by using the styleUrls property. An array of stylesheets can be passed into this option.

  • template - This is the portion of our component that holds our template. It is an integral part of the component as it allows us to tie logic from our component directly to a view. When defining a template, we can either write it inline, or we can opt to use templateUrl to link to an external template.

Export the Component

The exported class is where we can define any variables or functions that our component's template will be using:

// app/app.ts
export class AppComponent {
    componentName:string = 'AppComponent';
}

Angular 2 makes use of the ES2015 module syntax. By using the export statement, this component can be imported into different files in a project so it is a pivotal part of Angular 2.

Bootstrap our Component

We can use inline HTML and CSS:

// app/app.ts 
import { Component } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';

@Component({
    selector: 'my-app',
    styles: [`
        h1 {
          color:#545454;
          background:#02A8F4;
          padding:15px;
          box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
        }
    `],
    template: `
      <h1>Hello from the {{componentName}}.</h1>
    `
})

export class AppComponent {
    componentName:string = 'AppComponent';
}
bootstrap(AppComponent);

Or we can import our template and css file(s):

// app/app.ts 
import { Component } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';

@Component({
    selector: 'my-app',
    styleUrls: ['main.css', 'other.css'],
    templateUrl: 'main.html'
})

export class AppComponent {
    componentName:string = 'AppComponent';
}
bootstrap(AppComponent);

Nesting another Component

After creating a top-level component, we will now create a new component, so it can be imported by other component's.

We will look into:

First, tell Angular that you want this component to live inside of <my-weapons></my-weapons>. The template attached to this component is going to use the ngFor structural directive to iterate over a list of names.

The ngFor directive is the successor to ng-repeatfrom Angular 1.x. In addition to ngFor, Angular 2 provides developers with a handful of other camel-case directives.

In addition to the ngFor statement, we also create another componentName variable just like in the AppComponent component. You can use the same variable name and not have to worry about it messing with other components that utilize the same naming conventions.

// app/weapon.component.ts
import { Component } from '@angular/core'; 

@Component({
    selector: 'my-weapons'
    template: `
        <h1>Hello from the {{ componentName }}!</h1>
        <div *ngFor="let w of weapons">
            <h3>Name: {{ w.name }}</h3> 
            <h4>Type: {{ w.type }}</h4> 
        </div>
    `
})

Whenever we see an asterisk (*) prepended onto a directive, we immediately know that this will be using template tags (<template></template>) to render this piece of code.

This ability to use symbols to create dynamic behavior is what Angular calls "syntactical sugar". It makes the process of developing web applications a quicker process by cutting out bits of unnecessary code without cluttering up our template.

Angular 2 Syntax overview

The local variables #

The pound symbol # is used to declare a local variable in our templates. When working with templates in Angular 2, we can use this symbol to reference different DOM elements in our application. These local variables will act as references to specific DOM elements. Moreover, they provide us with the ability to do things like pull values from input fields and add dynamic functionality to a DOM element.

<a #weaponName>Click to shoot weapon</a>

Event Bindings ()

In Angular 1.x, we had to rely on directives like ng-click, ng-blur, ng-mouseenter, to handle different events. Angular 2 has dropped all of these directives and implemented a new, powerful syntax that allows developers to bind to any valid DOM event. For example:

By passing in the name of the event into parenthesis, which signifies an event binding in Angular 2. When working with events in Angular, it's important to know that events flow out of the template to the component.

<a (click)="shootWeapon()">Click to shoot weapon</a>

Similar to Angular 1.x, you can still pass the $event reference if you want to grab it inside your function. Just add it to the function call like so:

<a (click)="shootWeapon($event)">Click to shoot weapon</a>

Property Binding []

On the opposite side of event bindings () lie Angular's square-bracket syntax [] which signify a property binding.

When working with property bindings, any values flow from the component class to the template, whereas event bindings work vice-versa.

When working with Angular 1.x, we had to use directives like ng-src and ng-href to dynamically pass in values to DOM elements, however the use of property bindings allows us to drop the ng- prefix, and simply pass in the name of the property we wish to define.

<img [src]="urlToImage">

The use of property bindings is particularly key when define attribute directives.

<div [style.color]="color"></div>

WeaponsComponent Class to use @Injectable()

We access data by using services and some times these services make use of another feature of Angular 2 Dependency Injection and the use of @Injectable. Let's create our weapons object in a file located at app/weapons.service.ts

// app/weapon.service.ts

// 1. Import Injectable Decorator
import { Injectable } from '@angular/core';

// 2. Use @Injectable() to declare the WeaponService class as an Injectable
@Injectable()

/** 
    3.1. Create and export WeaponService  Class { }
    3.2. create weapons object and declare it to be an Array of any values/ 
    3.3. Add weapons object to the constructor function
    3.4. create getWeapons() function to call all weapon values. 
**/

// 3.1.
export class WeaponService { 

    // 3.2
    weapons:Array<any>;

    // 3.3
    constructor() {
        this.weapons = [
          { "name": "Yang's Recurve", "type": "bow" },
          { "name": "Short Bow", "type": "bow" },
          { "name": "Warden Bow", "type": "bow" },
          { "name": "Apprentice Warden Bow", "type": "bow" },
          { "name": "Uskang", "type": "bow" },
          { "name": "Ghoul King's Blade", "type": "sword" },
          { "name": "God Butcher", "type": "sword" },
          { "name": "Quinquennial Sword", "type": "sword" },
          { "name": "Second Quinquennial Sword", "type": "sword" },
          { "name": "Short Sword", "type": "sword" },
          { "name": "Apprentice's Wand", "type": "wand" },
          { "name": "Lesser Wand", "type": "wand" },
          { "name": "Oak Wand", "type": "wand" },
          { "name": "Starfire", "type": "wand" },
          { "name": "Unstable Scepter", "type": "wand" }
        ];
    }

    // 3.4
    getWeapons() {
        return this.weapons;
    }
}

1. First we need to import Injectable from the @angular/core library.

2. Then we declare this class to be an injectable using the @Injectable() decorator we just imported. When implemented, @Injectable() decorator will tell Angular that this class will be used for dependency injection.

3.1. We create our WeaponService class which will wrap all of the code we want our WeaponsComponent to access.

3.2. We create a weapons variable, and use TypeScript's type-system to tell Angular that this object is going to be an array of any values.

3.3. We add our data to the weapons object by adding it into our constructor function, which is where we put the data we want a particular class to receive.

3.. Finally, we create a getWeapons function to return our array of items. This is where we will often see http calls being made however our data is internal, therefore we can leave out having to import the @angular/http library.

Using our WeaponService as a dependency on our WeaponComponent

Now that our service is created, we need to do a few things in order to access it in our component. Import the service into our app/weapons.component.ts file.

// app/weapons.component.ts
import { Component } from '@angular/core';

// import the WeaponService into our component   
import { WeaponService } from 'app/weapon.service';

Register your service as a Provider

Next we need to pass WeaponService into our components providers option. This is the section of our component where we add any services that it makes use of.

// app/friend.component.ts
@Component({
  selector: 'my-weapons',
  providers: [WeaponService],
  styles: /** Styles are placed here **/
})

Inject it into the constructor() function

In order to our template access the WeaponService, we must inject it into the components constructor function. In this case, we are going to set our WeaponService equal to _WeaponService.

Once it's added to our constructor function, we are going to finish things off by assigning the weapons variable the result of our getWeapons() function.

// app/weapons.component.ts
export class WeaponsComponent {
    componentName:string = 'WeaponsComponent';

    // Inject WeaponService and assign it to _weaponService
    constructor(private _weaponService: WeaponService) {
        // Use .getWeapons() from app/weapon.service.ts to populate weapons object
        this.weapons = _weaponService.getWeapons();
    }
}

Final code for our app/weapons.component.ts should look like:

// app/weapons.component.ts
import { Component } from '@angular/core';
import { WeaponService } from 'app/weapon.service';

@Component({
    selector: 'my-weapons',
    providers : [WeaponService],
    styles: [
       `div { 
        background-color:#EFEFEF;
        margin-bottom:15px;
        padding:15px;
        border:1px solid #DDD;
        box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
        border-radius:3px;
      }
      h2 { 
        text-align: center;
      }`
    ],
    template: `
      <h2>Hello from the {{componentName}}!</h2>
      <div *ngFor="#w of weapons">
      <h4> Name : {{w.name}} </h4> <h4>Type: {{w.type}}</h4> 
      </div>`
})
export class WeaponsComponent {
    componentName:string = 'WeaponsComponent';

    // Inject WeaponService and assign it to _weaponService
    constructor(_weaponService: WeaponService) {
        // Use .getWeapons() from app/weapon.service.ts to populate weapons object
        this.weapons = _weaponService.getWeapons();
    }
}

Adding WeaponsComponent to main AppComponent

Our second component is wired up, and we are ready to nest it within our top-level component. To accomplish this, we need to make a few modifications to our app.ts file.

We have already seen how we can import core parts of Angular 2 via the ES2015 module syntax. Now, lets check out how we can use these same import statements to access code inside of our project.

// app/app.ts
import { Component } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';

/** Nested Component */ 
import { WeaponsComponent } from 'app/weapons.component';

In order to access WeaponsComponent, we need to add it into the components directive array. We need to add <my-weapons></my-weapons> to our inline-template or else it's not going to render. Also wrap this template in a <div> tag in order to show Angular 2's style encapsulation.

// app/app.ts
import { Component } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
/** Nested Component */ 
import { WeaponsComponent } from 'app/weapons.component';
@Component({
    selector: 'my-app',
    directives: [WeaponsComponent],
    styles: [
      `h1 {
        color:#545454;
        background:#02A8F4;
        padding:15px;
        box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
      }`
    ]
    template:
      `<div>
          <h1>Hello from the {{ componentName }}.</h1>
          <my-weapons></my-weapons>
      </div>`
})
export class AppComponent {
    componentName:string = 'AppComponent';
}
bootstrap(AppComponent)