Let's build an Angular 2 app

Context

Angular 1  vs. Angular2

Angular is a pattern, it is a way to design applications


UI components separated from business logic

 - Very declarative templates

 - Databind those templates with methods and objects

 - Dependency injection

Common in both Angular

Angular 1  vs. Angular2

Performance improvements
Better declarative APIs
New template systems

 - rendering in the server

Renderers

 - non DOM renders means web workers

 - other renderers like NativeScript

... Angular 2 is also

Briefing

Build a basic application with ...

  • A few components (reuse one of them)
  • A shared service
  • Http
  • Routing

Goals

Mockup

Giphy API

Powered By Giphy

"data": [
        {
            type: "gif",
            id: "FiGiRei2ICzzG",
            slug: "funny-cat-FiGiRei2ICzzG",
            url: "http://giphy.com/gifs/funny-cat-FiGiRei2ICzzG",
              ...
            images: {
                fixed_height: {
                    url: "http://media2.giphy.com/media/FiGiRei2ICzzG/200.gif",
                    width: "568",
                    height: "200",
                    size: "460622",
                },
                fixed_height_still: {
                    url: "http://media2.giphy.com/media/FiGiRei2ICzzG/200_s.gif",
                    width: "568",
                    height: "200"
                },
                fixed_height_downsampled: {
            ...

Architecture

Giffy-List

Search

Trending

App

GiphyAPI

Components
Services

Http

Routing

Project setup

Angular-CLI

Install angular-CLI


  npm install -g angular-cli

Create project


  ng new giffy

Serve


  ng serve

Nice development cycle

Components

Composite pattern

Composite objects into tree structures to represent part-whole hierarchies.

Design Patterns, GoF

An application will always have a root component

that contains all other components.

Every Angular 2 application will have a component tree.

Our App component tree 

Giffy-List

Search

Trending

App

Components

Components

An Angular class responsible for exposing data to a View and handling most of the view’s display and user-interaction logic.

angular.io

Components contain all the information needed to instantiate them:

  • How to render itself
  • Configure dependency injection
  • API of input and output properties

Components













export class AppExampleComponent {

  constructor() { }

}

Based on the ES2015 

module standard

Components


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

@Component({






})

export class AppExampleComponent {

  constructor() { }

}

@Component decorator is a function that adds metadata to a class.

Components


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

@Component({
  selector: 'app-example',





})

export class AppExampleComponent {

  constructor() { }

}

Selector associates an Angular component with a DOM element

Components


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

@Component({
  selector: 'app-example',
  templateUrl: 'app-example.component.html',
  styleUrls: ['app-example.component.css'],



})

export class AppExampleComponent {

  constructor() { }

}

Information on how to render itself

Components


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

@Component({
  selector: 'app-example',
  templateUrl: 'app-example.component.html',
  styleUrls: ['app-example.component.css'],
  directives: [],
  providers: [],
  ...
})

export class AppExampleComponent {

  constructor() { }

}

Component configures dependency injection

Components


import { Component, Input, Ouput } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: 'app-example.component.html',
  styleUrls: ['app-example.component.css'],
  directives: [],
  providers: [],
  ...
})

export class AppExampleComponent {

  constructor() { }

  @Input() propertyName; // property bindings
  @Output() eventName;   // event bindings

}

Public API of input and output properties

List Component

Create Giffy List Component

Directive dependencies

Template Syntax

Angular 2 removes the need for many built-in directives (e.g. ng-click, ng-focus, ng-blur, ng-keyup, ...)

aprox 20 of them are gone.

 

There are only 6 built-in directives:

NgClass, NgStyle, NgIf, NgSwitch, NgFor & NgModel

 

Just attach to the DOM event

Property binding

One-way property bindings bind a DOM property to a value or expression


  <img [src]="fixedHeight.url" />

  <div [hidden]="!isVisible" > .. </div>

  <p [class.specialClass]="isSpecial"> .. </p>

  <span [style.color]="textColor"> .. </span>

Event Binding

Event bindings are used to execute an expression when an event occurs

 

The binding sends information about the event, including data values, through an event object named $event.


  <div (click)="activate()"> .. </div>

  <input (blur)="save()" />

  <img (mouseover)="sort($event)" />

Two way Binding

Simplify with ngModel directive, it can be used to create a "two-way" binding


  <input [(ngModel)]="user.name">

Property and event binding

<input [value]="user.name"
  (input)="user.name=$event.target.value">

Binding summary

Property and events

Template directive *ngFor 

Input and Output API

Services

Step 1 - Create

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

@Injectable()
export class GiphyAPIService {

  constructor() { }

  getTrending() {
      // ..
  }
}

We can create services using ES2015 classes and adding @Injectable()

Step 2 - Import 

import { GiphyAPIService } from './localPath';

@Component({
    selector: ..,
    ..
    providers: [GiphyAPIService],
    ..
})
export class ExampleComponent {

  ..

}

Components configure dependency injection in providers array.

Available for all children.

Step 3 - Inject

When a component depends on a service, you do not create this service yourself. Request it on the constructor, and angular will provide you one.

// with DI
constructor(public giphyAPI: GiphyAPIService) { } // GOOD

// without DI
constructor() {
  this.giphyAPI = new GiphyAPIService(); // BAD
}

Angular 2 has one API for injecting dependencies into components.

Create Giphy API

Import+Inject Giphy API

Http

Inject Http Service

Http is an injectable class with methods to perform http requests.

import {Http} from '@angular/http';
import {Injectable} from '@angular/core';

@Injectable()
class GiphyAPIService {
  constructor(private http: Http) {

  }
}

Import Http Service

Http get observables

Http returns an Observable which will emit a single response it's received.

class GiphyAPIService {
  ...
  getContacts() {
    return this.http.get('http://api.gihpy.com/trending/..')
      .map((res) => { return res.json(); })
      .map((data) => { return data.items; });
  }
}

Get data

Recap

Actual Component tree

Giffy-List

App

GiphyAPI

Components
Service

Fast forward

  • New Search Component
  • New Trending Component
  • Search has an input field
  • Some CSS classes
  • ...

 

New component tree

Giffy-List

Search

Trending

App

Components

Routing

Provide Router

 Each Route Definition has a path, a component, and an optional name.

import { provideRouter, RouterConfig } from '@angular/router';

const routes: RouterConfig = [
  { path: 'users', component: UserListComponent },
  { path: 'user/:id', component: UserDetailComponent },
  { path: '**', component: PageNotFoundComponent }
];

export const appRouterProviders = [
  provideRouter(routes)
];

RC10

Provide Router

import { ModuleWithProviders }  from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { SearchComponent }      from './search/search.component';
import { TrendingComponent }      from './trending/trending.component';

const appRoutes: Routes = [
  {
    path: 'search', component: SearchComponent
  },
  {
    path: 'trending', component: TrendingComponent
  },
  {
    path: '**', component: SearchComponent 
  }
];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

Final Release

Bootstrap with Router 

Bootstrap our application with an array of routes using the provideRouter function.

import { appRouterProviders } from './app.routes';

bootstrap(AppComponent, [
  appRouterProviders
])

RC10

Bootstrap with Router 

Now it is added into the root NgModule.


import { routing } from './app.routes';

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    HttpModule,
    routing
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Final Release

Add Router Links

<router- outlet> is placeholder that Angular dynamically fills based on the application's route

  <nav>
    <a routerLink="/search" routerLinkActive="active">Search</a>
    <a routerLink="/trending" routerLinkActive="active">Trending</a>
  </nav>
  <router-outlet></router-outlet>

Config Routes

Import Routes

Router Links

Conclusions

Components, are the most important.

Component blocks build applications in trees.

Angular 2 offers a simplified API.

Q & A

Gracias!

Angular 2 - your first steps

By Carlos Morales

Angular 2 - your first steps

Slides presented at Zürich AngularJS Meetup (https://www.meetup.com/AngularJS-ZRH/events/233032337/)

  • 1,605