0% found this document useful (0 votes)
136 views

Pluralsight - Angular Getting Started

Uploaded by

Iulian Sirbu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
136 views

Pluralsight - Angular Getting Started

Uploaded by

Iulian Sirbu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 358

Angular: Getting Started

INTRODUCTION

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Angular Is …

A JavaScript framework
For building client-side applications
Using HTML, CSS and JavaScript
Why Angular?

Expressive Powerful Modular Built-in


HTML Data By Design Back-End
Binding Integration
Why a New Angular?

Built for Modern Simplified Enhances


API Productivity
Speed
Module
Overview Anatomy of an Angular Application
Getting the Most from This Course
Sample Application
Course Outline
Anatomy of an Angular Application

Application
= Component
+ Component
+ Component …
Services
Component

Class

= + +
Properties
Component Template Metadata

Methods
Angular Modules

Root Feature
Angular Module Angular Module

Component Component

Component Component

Component Component

Component Component
Prerequisites

Required Helpful Not Required

• JavaScript • Object-oriented • Prior knowledge of


• HTML programming Angular
• CSS (OOP) concepts • Prior knowledge of
• C++, C#, Java, … TypeScript
Thoughts? Comments? Questions?

@deborahkurata
Blog Post
http://blogs.msmvps.com/deborahk/angular-2-getting-started-problem-solver/
Checklist

Review module concepts


Code along assistance
Revisit as you build
GitHub Repository

https://github.com/DeborahK/Angular-GettingStarted
Demo

Sample Application in Action


Sample Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
First Things First

Introduction to Components

Course Templates, Interpolation, and Directives

Outline Data Binding & Pipes

More on Components

Building Nested Components

Services and Dependency Injection

Retrieving Data Using Http

Navigation and Routing

Angular Modules

Building, Testing and Deploying with the CLI


First Things First

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Module
Overview Selecting a Language
Selecting an Editor
Setting up an Angular Application
About Modules
JavaScript Language Specification

ECMAScript (ES)
ES 3
ES 5
ES 2015 (formerly known as ES 6)
- Must be transpiled
Selecting a Language

ES 5 ES 2015 TypeScript Dart


• Runs in the • Lots of new • Superset of • No
browser features JavaScript JavaScript
• No compile (classes, let, • Strong
required arrow, etc.) typing
• Great IDE
tooling
What Is TypeScript?

Open source language


Superset of JavaScript
Transpiles to plain JavaScript
Strongly typed
- TypeScript type definition files (*.d.ts)

Class-based object-orientation
Learning More

TypeScript Playground
http://www.typescriptlang.org/Playground/

Pluralsight Courses
"TypeScript Fundamentals"
"AngularJS with TypeScript"
"Using ES6 with TypeScript"
TypeScript Editors

Visual Studio

Visual Studio Code

WebStorm

Atom

Eclipse

Others
Visual Studio Code

https://code.visualstudio.com/
Learning More

Visual Studio Code Site


https://code.visualstudio.com/
Pluralsight Course
"Visual Studio Code"
Setting up Our Environment

npm
Set up the Angular application
npm

Node Package Manager


Command line utility
Installs libraries, packages, and
applications
https://www.npmjs.com/
Setting up an Angular Application

1. Create an application folder


2. Add package definition and
configuration files
3. Install the packages
4. Create the app's Angular Module
5. Create the main.ts file
6. Create the host Web page (index.html)
Setting up an Angular Application
Manually perform each step
Download the results of these steps
https://github.com/angular/quickstart
Angular CLI
https://github.com/angular/angular-cli
Starter files
https://github.com/DeborahK/Angular-
GettingStarted
Modules

AngularJS TypeScript
Modules Modules

ES 2015 Angular
Modules Modules
ES 2015 Modules

Export Import
product.ts product-list.ts

import { Product } from


export class Product{ './product'
}

product.js
Transpile

function Product() {
}
Angular Modules

Root Feature Shared


Angular Module Angular Module Module

Component Component Component

Component Component

Component Component

Component Component
Modules

ES Modules Angular Modules


Code files that Code files that
import or export something organize the application into cohesive
blocks of functionality
Organize our code files Organize our application
Modularize our code Modularize our application
Promote code reuse Promote application boundaries
Web
Web Browser Server

URL Request (www.mysite.com)

index.html
Response

JavaScript
Summary Selecting a Language
Selecting an Editor
Setting up an Angular Application
About Modules
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Introduction to Components

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Module
Overview What Is a Component?
Creating the Component Class
Defining the Metadata with a Decorator
Importing What We Need
Bootstrapping Our App Component
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
What Is a Component?

Class

= + +
Properties
Component Template Metadata

Methods

• View layout • Code supporting • Extra data for


• Created with HTML the view Angular
• Includes binding • Created with • Defined with a
and directives TypeScript decorator
• Properties: data
• Methods: logic
Component
app.component.ts Import
import { Component } from '@angular/core';

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1> Metadata &
<div>My First Component</div> Template
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management'; Class
}
Creating the Component Class
app.component.ts
app.component.ts

export class AppComponent {


pageTitle: string = 'Acme Product Management';
}

class
Class Name
keyword

export Component Name


keyword when used in code
Creating the Component Class
app.component.ts

export class AppComponent {


pageTitle: string = 'Acme Product Management';
}

Property Default
Data Type
Name Value

Methods
Defining the Metadata
app.component.ts

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div>
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
Decorator
A function that adds metadata to a class, its members, or its
method arguments.
Prefixed with an @.
Angular provides built-in decorators.

@Component()
Defining the Metadata
app.component.ts
Component
@Component({
decorator
selector: 'pm-root',
template: ` Directive Name
<div><h1>{{pageTitle}}</h1> used in HTML
<div>My First Component</div>
</div>
` View Layout
})
export class AppComponent {
pageTitle: string = 'Acme Product Management'; Binding
}
Importing What We Need

Before we use an external function or class,


we define where to find it
import statement
import allows us to use exported members
from external ES modules
Import from a third-party library, our own
ES modules, or from Angular
Angular Is Modular

@angular/ @angular/ @angular/ @angular/


core animate http router

https://www.npmjs.com/~angular
Importing What We Need
app.component.ts

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div>
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
Importing What We Need
app.component.ts
import { Component } from '@angular/core'; import keyword

@Component({ Angular library


selector: 'pm-root', module name
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div> Member name
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
Completed Component
app.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div>
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
Demo

Creating the App Component


Bootstrapping Our App Component

Host the application


Defining the Angular module
Single Page Application (SPA)

index.html contains the main page for the


application
This is often the only Web page of the
application
Hence an Angular application is often
called a Single Page Application (SPA)
Hosting the Application

index.html app.component.ts
<body> import { Component } from '@angular/core';
<pm-root></pm-root>
</body> @Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div>
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
BrowserModule

Organization
AppModule Boundaries
Template resolution
environment
AppComponent

Imports
Exports
Declarations
Providers
Bootstrap
Defining the Angular Module
app.module.ts
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 { }
Demo
Bootstrapping Our
App Component
Component Checklist

Class -> Code


Decorator -> Metadata
Import what we need
Component Checklist: Class
Clear name
- Use PascalCasing
- Append "Component" to the name

export keyword
Data in properties
- Appropriate data type
- Appropriate default value
- camelCase with first letter lowercase

Logic in methods
- camelCase with first letter lowercase
Component Checklist: Metadata

Component decorator
- Prefix with @; Suffix with ()

selector: Component name in HTML


- Prefix for clarity

template: View's HTML


- Correct HTML syntax
Component Checklist: Import

Defines where to find the members that


this component needs
import keyword
Member name
- Correct spelling/casing

Module path
- Enclose in quotes
- Correct spelling/casing
Something's Wrong! Checklist

F12 is your friend


Recheck your code
- HTML
• Close tags
• Angular directives are case sensitive
- TypeScript
• Close braces
• TypeScript is case sensitive
Something's Wrong! Checklist (cont.)

Check my blog for a solution


- http://blogs.msmvps.com/deborahk/
angular-2-getting-started-problem-
solver/
Post to the course discussion
- https://app.pluralsight.com/library/cours
es/angular-2-getting-started/discussion
Summary What Is a Component?
Creating the Component Class
Defining the Metadata with a Decorator
Importing What We Need
Hosting Our App Component
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Templates, Interpolation, and
Directives

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Component

Class

= + +
Properties
Component Template Metadata

Methods
Module
Overview Building a Template
Using a Component as a Directive
Binding with Interpolation
Adding Logic with Directives
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Component
app.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<div>My First Component</div>
</div>
`
})
export class AppComponent {
pageTitle: string = 'Acme Product Management';
}
Defining a Template in a Component

Inline Template Inline Template Linked Template

template: template: ` templateUrl:


"<h1>{{pageTitle}}</h1>" './product-list.component.html'
<div>
<h1>{{pageTitle}}</h1>
<div>
My First Component
</div>
</div>
`
ES 2015
Back Ticks
Product List View
Product List View
Product List View
Product List View

http://getbootstrap.com/
Building the Component
product-list.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'pm-products',
templateUrl: './product-list.component.html'
})
export class ProductListComponent {
pageTitle: string = 'Product List';
}
Using a Component as a Directive
app.component.ts product-list.component.ts
@Component({ @Component({
selector: 'pm-root', selector: 'pm-products',
template: ` templateURL:
<div><h1>{{pageTitle}}</h1> './product-list.component.html'
<div>My First Component</div> })
</div>` export class ProductListComponent { }
})
export class AppComponent { }
Using a Component as a Directive
app.component.ts product-list.component.ts
@Component({ @Component({
selector: 'pm-root', selector: 'pm-products',
template: ` templateURL:
<div><h1>{{pageTitle}}</h1> './product-list.component.html'
<pm-products></pm-products> })
</div>` export class ProductListComponent { }
})
export class AppComponent { }
BrowserModule

AppModule

AppComponent

Imports
Exports
Declarations
Providers
Bootstrap
BrowserModule

AppModule

AppComponent

ProductList -
Component

Imports
Exports
Declarations
Providers
Bootstrap
Binding
Coordinates communication between the component's
class and its template and often involves passing data.
Class

Properties
Template
Methods
Interpolation
Template Class

<h1>{{pageTitle}}</h1> export class AppComponent {


pageTitle: string =
{{'Title: ' + pageTitle}} 'Acme Product Management';
}getTitle(): string {...};
{{2*20+1}} }

{{'Title: ' + getTitle()}}

<h1 innerText={{pageTitle}}></h1>
Directive
Custom HTML element or attribute used to power up
and extend our HTML.
• Custom
• Built-In
Custom Directives
app.component.ts product-list.component.ts
@Component({ @Component({
selector: 'pm-root', selector: 'pm-products',
template: ` templateURL:
<div><h1>{{pageTitle}}</h1>
<pm-products></pm-products> './product-list.component.html'
</div> })
` export class ProductListComponent { }
})
export class AppComponent { }
Angular Built-in Directives

•*ngIf: If logic
Structural
Directives
•*ngFor: For loops
*ngIf Built-In Directive
<div class='table-responsive'>
<table class='table' *ngIf='products && products.length'>
<thead> ...
</thead>
<tbody> ...
</tbody>
</table>
</div>
BrowserModule

AppModule

AppComponent

ProductList -
Component

Imports
Exports
Declarations
Providers
Bootstrap
*ngFor Built-In Directive
<tr *ngFor='let product of products'> Template
<td></td> input variable
<td>{{ product.productName }}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate }}</td>
<td>{{ product.price }}</td>
<td>{{ product.starRating }}</td>
</tr>
for…of vs for…in

for…of
let nicknames= ['di', 'boo', 'punkeye'];
• Iterates over iterable for (let nickname of nicknames) {
objects, such as an array. console.log(nickname);
• Result: di, boo, punkeye }

for…in
let nicknames= ['di', 'boo', 'punkeye'];
• Iterates over the
properties of an object. for (let nickname in nicknames) {
console.log(nickname);
• Result: 0, 1, 2 }
*ngFor Built-In Directive
<tr *ngFor='let product of products'>
<td></td>
<td>{{ product.productName }}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate }}</td>
<td>{{ product.price }}</td>
<td>{{ product.starRating }}</td>
</tr>
Checklist: Template
Inline template
- For short templates
- Specify the template property
- Use the ES 2015 back ticks for multiple
lines
- Watch syntax

Linked template
- For longer templates
- Specify the templateUrl property
- Define the path to the HTML file
Checklist: Component as a Directive
product-list.component.ts
@Component({
selector: 'pm-products',
templateURL:
'./product-list.component.html'
})
export class ProductListComponent { }

app.component.ts app.module.ts
@Component({ @NgModule({
selector: 'pm-root', imports: [ BrowserModule ],
template: ` declarations: [
<div><h1>{{pageTitle}}</h1> AppComponent,
<pm-products></pm-products> ProductListComponent ],
</div>` bootstrap: [ AppComponent ]
}) })
export class AppComponent { } export class AppModule { }
Checklist: Interpolation

One way binding


- From component class property to an
element property.
Defined with double curly braces
- Contains a template expression
- No quote needed
Checklist: Structural Directives
*ngIf and *ngFor
- Prefix with an asterisk
- Assign to a quoted string expression

*ngIf
- Expression is evaluated as a true or false
value
*ngFor
- Define the local variable with let

- Specify 'of': 'let product of products'


Summary Building a Template
Using a Component as a Directive
Binding with Interpolation
Adding Logic with Directives
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Data Binding & Pipes

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Component DOM

EVENTS

PROPERTIES
Module
Overview Property Binding
Handling Events with Event Binding
Handling Input with Two-way Binding
Transforming Data with Pipes
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Property Binding
<img [src]='product.imageUrl'>

<img src={{product.imageUrl}}>

<img Element
src=' Template
' '{{product.imageUrl}}'>
[ ] http://openclipart.org/
Binding
Property
Target Binding
Expression
Source
Event Binding
Template Class

<h1>{{pageTitle}}</h1>
<img [src]='product.imageUrl'>
<button (click)='toggleImage()'>
export class ListComponent {
pageTitle: string = 'Product List';
https://developer.mozilla.org/en-US/docs/Web/Events
products: any[] = […];
toggleImage(): void {…}
() ''
}
Target Event Template
Statement
Two-way Binding
Template Class

<input [(ngModel)]='listFilter'>
export class ListComponent {
listFilter: string = 'cart';
}
Two-way Binding
Template Class

<input [(ngModel)]='listFilter'>
export class ListComponent {
listFilter: string = 'cart';
}
Two-way Binding
Template Class

<input [(ngModel)]='listFilter'>
export class ListComponent {
listFilter: string = 'cart';
}
Two-way Binding
Template Class

<input [(ngModel)]='listFilter'>
export class ListComponent {
listFilter: string = 'cart';
}

[()]
Banana in a Box
BrowserModule

AppModule

AppComponent

ProductList -
Component

Imports
Exports
Declarations
Providers
Bootstrap
BrowserModule FormsModule

AppModule

AppComponent

ProductList -
Component

Imports
Exports
Declarations
Providers
Bootstrap
Transforming Data with Pipes

Built-in pipes
Transform
bound • date
• number, decimal, Custom
properties percent, currency pipes
before • json, slice
display • etc
Pipe Examples

{{ product.productCode | lowercase }}

<img [src]='product.imageUrl'
[title]='product.productName | uppercase'>

{{ product.price | currency | lowercase }}

{{ product.price | currency:'USD':true:'1.2-2' }}
Data Binding
DOM product-list.component.ts
@Component({
selector: 'pm-products',
templateURL: './product-list.component.html'
})
export class ProductListComponent {
pageTitle: string = 'Product List';
listFilter: string = 'cart';
products: any[] = […];
toggleImage(): void {…}
}
Data Binding

Interpolation: {{pageTitle}}

Property Binding: <img [src]='product.imageUrl'>

DOM Component
Event Binding: <button (click)='toggleImage()'>

Two-Way Binding: <input [(ngModel)]='listFilter'/>


Checklist: ngModel

product-list.component.html app.module.ts
<div class='col-md-4'> @NgModule({
<input type='text' imports: [
[(ngModel)]='listFilter' /> BrowserModule,
</div> FormsModule ],
declarations: [
AppComponent,
ProductListComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Checklist: Pipes

Pipe character |
Pipe name
Pipe parameters
- Separated with colons

Example
- {{ product.price |
currency:'USD':true:'1.2-2' }}
Summary Property Binding
Handling Events with Event Binding
Handling Input with Two-way Binding
Transforming Data with Pipes
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
More on Components

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Improving Our Components

Strong typing & interfaces

Encapsulating styles

Lifecycle hooks

Custom pipes

Nested components
Module
Overview Defining an Interface
Encapsulating Component Styles
Using Lifecycle Hooks
Building a Custom Pipe
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Strong Typing
export class ProductListComponent {
pageTitle: string = 'Product List';
showImage: boolean = false;
listFilter: string = 'cart';
message: string;

products: any[] = […];

toggleImage(): void {
this.showImage = !this.showImage;
}

onRatingClicked(message: string): void {


this.message = message;
}
Interface
A specification identifying a related set of properties
and methods.
A class commits to supporting the specification by
implementing the interface.
Use the interface as a data type.
Development time only!
Interface Is a Specification
export interface IProduct { export
productId: number; keyword
productName: string;
productCode: string; Interface
releaseDate: Date; Name
price: number;
description: string;
interface
starRating: number;
keyword
imageUrl: string;
calculateDiscount(percent: number): number;
}
Using an Interface as a Data Type
import { IProduct } from './product';
export class ProductListComponent {
pageTitle: string = 'Product List';
showImage: boolean = false;
listFilter: string = 'cart';

products: IProduct[] = […];

toggleImage(): void {
this.showImage = !this.showImage;
}
}
Handling Unique Component Styles

Templates sometimes require unique styles


We can inline the styles directly into the
HTML
We can build an external stylesheet and link
it in index.html
There is a better way!
Encapsulating Component Styles
styles
@Component({

• selector: 'pm-products',
templateUrl: './product-list.component.html',
• styles: ['thead {color: #337AB7;}']})

styleUrls


@Component({
• selector: 'pm-products',
• templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']})

Component Lifecycle

Create
and Process
Create Render Destroy
render changes
children
Component Lifecycle Hooks

OnInit: Perform component initialization,


retrieve data
OnChanges: Perform action after change to
input properties
OnDestroy: Perform cleanup
Using a Lifecycle Hook
import { Component, OnInit } from '@angular/core';
export class ProductListComponent
implements OnInit {
pageTitle: string = 'Product List';
showImage: boolean = false;
listFilter: string = 'cart';
products: IProduct[] = […];

ngOnInit(): void {
console.log('In OnInit');
}
}
Transforming Data with Pipes

Built-in pipes
Transform
bound • date
• number, decimal, Custom
properties percent, currency pipes
before • json, slice
display • etc
Building a Custom Pipe
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
name: 'convertToSpaces'
})
export class ConvertToSpacesPipe
implements PipeTransform {

transform(value: string,
character: string): string {
}
}
Using a Custom Pipe
Template

<td>{{ product.productCode | convertToSpaces:'-'}}</td>

Pipe
transform(value: string, character: string): string {

}
BrowserModule FormsModule

AppModule

AppComponent

ProductList -
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations
Providers
Bootstrap
Using a Custom Pipe
Template

<td>{{ product.productCode | convertToSpaces:'-'}}</td>


Module
@NgModule({
imports: [
BrowserModule,
FormsModule ],
declarations: [
AppComponent,
ProductListComponent,
ConvertToSpacesPipe ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Filtering Data

<tr *ngFor='let product of products | productFilter: listFilter'>


"Angular doesn't offer such pipes
because they perform poorly and
prevent aggressive minification."
angular.io
"The Angular team and many
experienced Angular developers
strongly recommend moving filtering
and sorting logic into the component
itself."
angular.io
Checklist: Interfaces

Defines custom types


Creating interfaces:
- interface keyword
- export it

Implementing interfaces:
- implements keyword & interface name
- Write code for each property & method
Checklist: Encapsulating Styles

styles property
- Specify an array of style strings

styleUrls property
- Specify an array of stylesheet paths
Checklist: Using Lifecycle Hooks

Import the lifecycle hook interface


Implement the lifecycle hook interface
Write code for the hook method
Checklist: Building a Custom Pipe

Import Pipe and PipeTransform


Create a class that implements
PipeTransform
- export the class

Write code for the Transform method


Decorate the class with the Pipe decorator
Checklist: Using a Custom Pipe
Import the custom pipe
Add the pipe to the declarations array of
an Angular module
Any template associated with a component
that is also declared in that Angular
module can use that pipe
Use the Pipe in the template
- Pipe character
- Pipe name
- Pipe arguments (separated with colons)
Summary Defining an Interface
Encapsulating Component Styles
Using Lifecycle Hooks
Building a Custom Pipe
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Building Nested Components

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Using a Component

As a Directive As a Routing target

App Full
Component page
OR Nested style
Component view

<body>
<pm-root></pm-root>
</body>
What Makes a Component Nest-able?

Its template only manages a fragment of a


larger view
It has a selector
It optionally communicates with its
container
Module
Building a Nested Component
Overview
Using a Nested Component
Passing Data to a Nested Component
Using @Input
Raising an Event from a Nested
Component Using @Output
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Building a Nested Component
Container Component
Template

Nested Component <pm-star> </pm-star>


Template

Class

Class
Building a Nested Component
Container Component
Template

Nested Component
<pm-star> </pm-star>
Template
Input

Output

Class

Class
Product List View
Product List View
Using a Nested Component as a Directive
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
rating: number;
starWidth: number;
product-list.component.html }
<td>
{{ product.starRating | number }}
</td>
Using a Nested Component as a Directive
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
rating: number;
starWidth: number;
product-list.component.html }

<td>
<pm-star></pm-star>
</td>
BrowserModule FormsModule

AppModule

AppComponent

ProductList -
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent
Providers
Bootstrap
Telling Angular About Our Component
app.module.ts
...
import { StarComponent } from './shared/star.component';

@NgModule({
imports: [
BrowserModule,
FormsModule ],
declarations: [
AppComponent,
ProductListComponent,
ConvertToSpacesPipe,
StarComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Passing Data to a Nested Component (@Input)
Container Component
Template

Nested Component
<pm-star> </pm-star>
Template
Input @Input()

Class

Class
Passing Data to a Nested Component (@Input)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
product-list.component.html }
<td>
<pm-star></pm-star>
</td>
Passing Data to a Nested Component (@Input)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
product-list.component.html }
<td>
<pm-star [rating]='product.starRating'>
</pm-star>
</td>
Raising an Event (@Output)
Container Component
Template

Nested Component
<pm-star> </pm-star>
Template
Input @Input()

Output @Output()
Class

Class
Raising an Event (@Output)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();
}

product-list.component.html
<td>
<pm-star [rating]='product.starRating'>
</pm-star>
</td>
Raising an Event (@Output)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();

onClick() {
this.notify.emit('clicked!');
product-list.component.html }
}
<td>
<pm-star [rating]='product.starRating'> star.component.html
</pm-star> <div (click)='onClick()'>
</td> ... stars ...
</div>
Raising an Event (@Output)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { } export class StarComponent {
@Input() rating: number;
starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();

onClick() {
this.notify.emit('clicked!');
product-list.component.html }
}
<td>
<pm-star [rating]='product.starRating' star.component.html
(notify)='onNotify($event)'> <div (click)='onClick()'>
</pm-star> ... stars ...
</td> </div>
Raising an Event (@Output)
product-list.component.ts star.component.ts
@Component({ @Component({
selector: 'pm-products', selector: 'pm-star',
templateURL: './product-list.component.html' templateURL: './star.component.html'
}) })
export class ProductListComponent { export class StarComponent {
onNotify(message: string): void { } @Input() rating: number;
} starWidth: number;
@Output() notify: EventEmitter<string> =
new EventEmitter<string>();

onClick() {
this.notify.emit('clicked!');
product-list.component.html }
}
<td>
<pm-star [rating]='product.starRating' star.component.html
(notify)='onNotify($event)'> <div (click)='onClick()'>
</pm-star> ... stars ...
</td> </div>
Nest-able Component's Public API
Container Component
Template

Nested Component
<pm-star> </pm-star>
Template
Input @Input()

Output @Output()
Class

Class
Checklist: Nested Component
Input decorator
- Attached to a property of any type
- Prefix with @; Suffix with ()

Output decorator
- Attached to a property declared as an
EventEmitter
- Use the generic argument to define the
event payload type
- Use the new keyword to create an
instance of the EventEmitter
- Prefix with @; Suffix with ()
Checklist: Container Component
Use the directive
- Directive name -> nested component's
selector
Use property binding to pass data to the
nested component
Use event binding to respond to events
from the nested component
- Use $event to access the event payload
passed from the nested component
Building a Nested Component
Summary
Using a Nested Component
Passing Data to a Nested Component
Using @Input
Raising an Event from a Nested
Component Using @Output
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Services and Dependency Injection

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Products Logging
Service
A class with a focused purpose.
Used for features that:
• Are independent from any particular component
• Provide shared data or logic across components
• Encapsulate external interactions
Module
Overview How Does It Work?
Building a Service
Registering the Service
Injecting the Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
How Does It Work?

Service Component
export class myService {} let svc = new myService();

svc
How Does It Work?
Injector

log math svc

Service Component
export class myService {} constructor(private _myService) {}
Dependency Injection
A coding pattern in which a class receives the instances
of objects it needs (called dependencies) from an
external source rather than creating them itself.
Building a Service

Import
what we
need

Define the
metadata
with a
decorator

Create the
service class
Building a Service
product.service.ts
import { Injectable } from '@angular/core'

@Injectable()
export class ProductService {

getProducts(): IProduct[] {
}

}
Registering the Service
Injector

log math svc

Service Component
export class myService {} constructor(private _myService) {}
Registering a Service
Register a provider
- Code that can create or return a service
- Typically the service class itself

Define in component OR Angular module


metadata
Registered in component:
- Injectable to component AND its children

Registered in Angular module:


- Injectable everywhere in the application
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Registering a Provider
app.component.ts
...
import { ProductService } from './products/product.service';

@Component({
selector: 'pm-root',
template: `
<div><h1>{{pageTitle}}</h1>
<pm-products></pm-products>
</div>
`,
providers: [ProductService]
})
export class AppComponent { }
Injecting the Service
Injector

log math svc

Service Component
export class myService {} constructor(private _myService) {}
Injecting the Service
product-list.component.ts
...

@Component({
selector: 'pm-products',
templateUrl: './product-list.component.html'
})
export class ProductListComponent {

constructor() {
}

}
Injecting the Service
product-list.component.ts
...
import { ProductService } from './product.service';

@Component({
selector: 'pm-products',
templateUrl: './product-list.component.html'
})
export class ProductListComponent {
private _productService;
constructor(productService: ProductService) {
_productService = productService;
}

}
Injecting the Service
product-list.component.ts
...
import { ProductService } from './product.service';

@Component({
selector: 'pm-products',
templateUrl: './product-list.component.html'
})
export class ProductListComponent {

constructor(private _productService: ProductService) {


}

}
Checklist: Creating a Service
Service class
- Clear name
- Use PascalCasing
- Append "Service" to the name
- export keyword

Service decorator
- Use Injectable
- Prefix with @; Suffix with ()

Import what we need


Checklist: Registering a Service in a Component
Select the appropriate level in the hierarchy
- Root component if service is used
throughout the application
- Specific component if only that
component uses the service
- Otherwise, common ancestor

Component metadata
- Set the providers property
- Pass in an array

Import what we need


Checklist: Dependency Injection

Specify the service as a dependency


Use a constructor parameter
Service is injected when component is
instantiated
Summary How Does It Work?
Building a Service
Registering the Service
Injecting the Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Retrieving Data Using Http

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Web
Web Browser Server

index.html index.html

JavaScript JavaScript

(http://mysite/api/products/5)
Web
Service
Response

Data
DB
Module
Overview Observables and Reactive Extensions
Sending an Http Request
Exception Handling
Subscribing to an Observable
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Observables and Reactive Extensions

Help manage asynchronous data


Treat events as a collection
- An array whose items arrive
asynchronously over time
Are a proposed feature for ES 2016
Use Reactive Extensions (RxJS)
Are used within Angular
Observable Operators

Methods on observables that compose new


observables
Transform the source observable in some
way
Process each value as it is emitted
Examples: map, filter, take, merge, …
Observables
Promise vs Observable

Promise Observable
Provides a single future value Emits multiple values over time
Not lazy Lazy
Not cancellable Cancellable
Supports map, filter, reduce and similar
operators
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Sending an Http Request

Get GET

Product Data Web


Http Service
Service Response Response Server
Sending an Http Request
product.service.ts
...
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ProductService {
private _productUrl = 'www.myWebService.com/api/products';

constructor(private _http: HttpClient) { }

getProducts() {
return this._http.get(this._productUrl);

}
}
Registering the Http Service Provider
app.module.ts
...
import { HttpClientModule } from '@angular/common/http';

@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule ],
declarations: [
AppComponent,
ProductListComponent,
ConvertToSpacesPipe,
StarComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
BrowserModule FormsModule HttpClientModule

AppModule

AppComponent

ProductList -
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent
Providers
Bootstrap
Sending an Http Request
product.service.ts
...
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ProductService {
private _productUrl = 'www.myWebService.com/api/products';

constructor(private _http: HttpClient) { }

getProducts() {
return this._http.get(this._productUrl);

}
}
Sending an Http Request
product.service.ts
...
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ProductService {
private _productUrl = 'www.myWebService.com/api/products';

constructor(private _http: HttpClient) { }

getProducts() {
return this._http.get<IProduct[]>(this._productUrl);

}
}
Sending an Http Request
product.service.ts
...
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ProductService {
private _productUrl = 'www.myWebService.com/api/products';

constructor(private _http: HttpClient) { }

getProducts(): Observable<IProduct[]> {
return this._http.get<IProduct[]>(this._productUrl);

}
}
Exception Handling
product.service.ts
...
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
...

getProducts(): Observable<IProduct[]> {
return this._http.get<IProduct[]>(this._productUrl)
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}

private handleError(err: HttpErrorResponse) {


}
Subscribing to an Observable
x.then(valueFn, errorFn) //Promise
x.subscribe(valueFn, errorFn) //Observable
x.subscribe(valueFn, errorFn, completeFn) //Observable
let sub = x.subscribe(valueFn, errorFn, completeFn)

product-list.component.ts

ngOnInit(): void {
this._productService.getProducts()
.subscribe(products => this.products = products,
error => this.errorMessage = <any>error);
}
Http Checklist: Setup

Add HttpClientModule to the


imports array of one of the
application's Angular Modules
Http Checklist: Service
Import what we need
Define a dependency for the http client
service
- Use a constructor parameter

Create a method for each http request


Call the desired http method, such as get
- Pass in the Url

Use generics to specify the returned type


Add error handling
Http Checklist: Subscribing

Call the subscribe method of the returned


observable
Provide a function to handle an emitted
item
- Normally assigns a property to the
returned JSON object
Provide an error function to handle any
returned errors
Summary Observables and Reactive Extensions
Sending an Http Request
Exception Handling
Subscribing to an Observable
Learning More

Pluralsight Courses
- "Angular: Reactive Forms"
• Http and CRUD
- "Play by Play: Angular 2/RxJS/HTTP and
RESTful Services with John Papa and
Dan Wahlin"
• RxJS and Observables
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Navigation and Routing Basics

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Module
Overview How Does Routing Work?
Configuring Routes
Tying Routes to Actions
Placing the Views
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
BrowserModule FormsModule HttpClientModule

AppModule

AppComponent

ProductList -
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent

Providers
Bootstrap
BrowserModule FormsModule HttpClientModule

AppModule

ProductDetail -
AppComponent
Component

ProductList -
WelcomeComponent
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent

Providers
Bootstrap
How Routing Works

Configure a route for each component


Define options/actions
Tie a route to each option/action
Activate the route based on user action
Activating a route displays the
component's view
How Routing Works

<a routerLink="/products">Product List</a>

{ path: 'products', component: ProductListComponent }

product-list.component.ts
import { Component } from '@angular/core';

<router-outlet></router-outlet> @Component({
templateUrl: './product-list.component.html'
})
export class ProductListComponent { }
'products', ProductListComponent

'products/:id', ProductDetailComponent

'welcome', WelcomeComponent
Configuring Routes
app.module.ts
...
import { RouterModule } from '@angular/router';

@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
RouterModule
],
declarations: [
...
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Configuring Routes
app.module.ts
...
import { RouterModule } from '@angular/router';

@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot([])
],
declarations: [
...
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Configuring Routes
app.module.ts
...
import { RouterModule } from '@angular/router';

@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
RouterModule.forRoot([], { useHash: true })
],
declarations: [
...
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Configuring Routes

[
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent },
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
]
Navigating the Application Routes

Menu option, link, image or button that


activates a route
Typing the Url in the address bar /
bookmark
The browser's forward or back buttons
Tying Routes to Actions
Tying Routes to Actions
app.component.ts
...

@Component({
selector: 'pm-root',
template: `
<ul class='nav navbar-nav'>
<li><a>Home</a></li>
<li><a>Product List</a></li>
</ul>
`
})
Tying Routes to Actions
app.component.ts
...

@Component({
selector: 'pm-root',
template: `
<ul class='nav navbar-nav'>
<li><a [routerLink]="['/welcome']">Home</a></li>
<li><a [routerLink]="['/products']">Product List</a></li>
</ul>
`
})
Placing the Views
app.component.ts
...

@Component({
selector: 'pm-root',
template: `
<ul class='nav navbar-nav'>
<li><a [routerLink]="['/welcome']">Home</a></li>
<li><a [routerLink]="['/products']">Product List</a></li>
</ul>
<router-outlet></router-outlet>
`
})
How Routing Works

<a [routerLink]="['/products']">Product List</a>

{ path: 'products', component: ProductListComponent }

product-list.component.ts
import { Component } from '@angular/core';

<router-outlet></router-outlet> @Component({
templateUrl: './product-list.component.html'
})
export class ProductListComponent { }
Checklist: Displaying Components

Nest-able components
- Define a selector
- Nest in another component
- No route

Routed components
- No selector
- Configure routes
- Tie routes to actions
Checklist: Doing Routing

Configure routes
Tie routes to actions
Place the view
Routing Checklist: Configuring Routes
Define the base element
Add RouterModule
- Add each route (RouterModule.forRoot)
- Order matters

path: Url segment for the route


- No leading slash
- '' for default route
- '**' for wildcard route

component
- Not string name; not enclosed in quotes
Routing Checklist: Tying Routes to Actions

Add the RouterLink directive as an


attribute
- Clickable element
- Enclose in square brackets

Bind to a link parameters array


- First element is the path
- All other elements are route parameters
Routing Checklist: Placing the View

Add the RouterOutlet directive


- Identifies where to display the routed
component's view
- Specified in the host component's
template
Summary How Does Routing Work?
Configuring Routes
Tying Routes to Actions
Placing the Views
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Navigation and Routing
Additional Techniques

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Module
Overview
Passing Parameters to a Route
Activating a Route with Code
Protecting Routes with Guards
Application Architecture
Welcome
Component

App Product List


index.html
Component Component
Star
Component
Product Detail
Product Data Component
Service
Passing Parameters to a Route
Passing Parameters to a Route
app.module.ts
@NgModule({
imports: [
...,
RouterModule.forRoot([
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent },
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
])
],
declarations: [...],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Passing Parameters to a Route
product-list.component.html
<td>
<a [routerLink]="['/products', product.productId]">
{{product.productName}}
</a>
</td>

app.module.ts
{ path: 'products/:id', component: ProductDetailComponent }
Reading Parameters from a Route
product-detail.component.ts
import { ActivatedRoute } from '@angular/router';

constructor(private _route: ActivatedRoute) {


console.log(this._route.snapshot.paramMap.get('id'));
}

app.module.ts
{ path: 'products/:id', component: ProductDetailComponent }
Activating a Route with Code
Activating a Route with Code
product-detail.component.ts
import { Router } from '@angular/router';
...
constructor(private _router: Router) { }

onBack(): void {
this._router.navigate(['/products']);
}
Protecting Routes with Guards
CanActivate
- Guard navigation to a route

CanDeactivate
- Guard navigation from a route

Resolve
- Pre-fetch data before activating a route

CanLoad
- Prevent asynchronous routing
Building a Guard
product-guard.service.ts
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class ProductGuardService implements CanActivate {

canActivate(): boolean {
...
}
}
Registering a Guard
app.module.ts
...
import { ProductGuardService } from './products/product-guard.service';

@NgModule({
imports: [...],
declarations: [...],
providers: [ ProductGuardService ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Using a Guard
app.module.ts
@NgModule({
imports: [
...,
RouterModule.forRoot([
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id',
canActivate: [ProductGuardService ],
component: ProductDetailComponent },
...])
],
declarations: [...],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Routing Checklist: Passing Parameters
app.module.ts
{ path: 'products/:id', component: ProductDetailComponent }

product-list.component.html
<a [routerLink]="['/products', product.productId]">
{{product.productName}}
</a>

product-detail.component.ts
import { ActivatedRoute } from '@angular/router';

constructor(private _route: ActivatedRoute) {


console.log(this._route.snapshot.paramMap.get('id'));
}
Routing Checklist: Activate a Route with Code
Use the Router service
- Import the service
- Define it as a dependency

Create a method that calls the navigate


method of the Router service
- Pass in the link parameters array

Add a user interface element


- Use event binding to bind to the created
method
Routing Checklist: Protecting Routes with Guards

Build a guard service


- Implement the guard type (CanActivate)
- Create the method (canActivate())

Register the guard service provider


- Must be in an Angular module

Add the guard to the desired route


Summary
Passing Parameters to a Route
Activating a Route with Code
Protecting Routes with Guards
Learning More

"Angular Routing"
- Required, optional, & query parameters
- Prefetching with route resolvers
- Child and secondary router outlets
- Router guards
- Lazy loading
BrowserModule FormsModule HttpClientModule RouterModule

AppModule

ProductDetail -
AppComponent ProductService
Component

ProductList -
WelcomeComponent ProductGuardService
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent

Providers
Bootstrap
Angular Modules

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
BrowserModule

HttpClientModule RouterModule RouterModule CommonModule

AppModule ProductModule SharedModule

ProductList -
AppComponent ProductService StarComponent
Component

ProductDetail -
WelcomeComponent ProductGuardService CommonModule
Component

Imports ConvertToSpaces
FormsModule
Exports Pipe
Declarations
Providers
Bootstrap
Module
Overview What Is an Angular Module?
Angular Module Metadata
Creating a Feature Module
Defining a Shared Module
Revisiting AppModule
What Is an Angular Module?

A class with an NgModule decorator


Its purpose:
- Organize the pieces of our application
- Arrange them into blocks
Module
- Extend our application with capabilities
from external libraries
- Provide a template resolution
environment
- Aggregate and re-export
Angular Module

@angular
@angular @angular
@angular
module Module module Module
module Imports Exports module
Module

3rd party Route @angular


3rd party Component,
module Component
Directive,
module module module
Pipe
Provides Declares
Bootstraps

Imports
Componen Component,
Exports Service
t Component
Directive,
Declarations
Pipe
Providers
Bootstrap
AppComponent ... RouterModule
<li><a [routerLink]="['/welcome']">
ProductList -
Home</a></li>
Component <li><a [routerLink]="['/products']">
Product List</a></li>
ProductDetail - ...
Component <router-outlet></router-outlet>
...
WelcomeComponent

Angular Module
AppComponent RouterModule

ProductList - ... FormsModule


Component
<input type='text'
ProductDetail - [(ngModel)]='listFilter' />
Component ...

WelcomeComponent

Angular Module
AppComponent RouterModule

ProductList - ... FormsModule


Component
<tr *ngFor='let product of products'>
ProductDetail - <td>
<img *ngIf='showImage' BrowserModule
Component
...
WelcomeComponent

Angular Module
ConvertToSpaces
AppComponent RouterModule
Pipe

ProductList - ... FormsModule


Component
<td>{{ product.productCode |
ProductDetail - convertToSpaces: '-' }}
</td> BrowserModule
Component
...
WelcomeComponent

Angular Module
ConvertToSpaces
AppComponent RouterModule
Pipe

ProductList - ... StarComponent FormsModule


Component
<pm-star
ProductDetail - [rating]='product.starRating'
BrowserModule
(ratingClicked)='onRatingClicked($event)'>
Component
</pm-star>
WelcomeComponent ...

Angular Module
ConvertToSpaces
AppComponent RouterModule
Pipe

ProductList -
StarComponent FormsModule
Component

ProductDetail -
BrowserModule
Component

WelcomeComponent

Angular Module
Template Resolution Environment
Star-
Module
Component

Forms-
Module
Module

ProductList- Star-
Imports Component Component
Exports
Declarations
Providers
Bootstrap
Bootstrap Array

app.module.ts
AppModule
...
bootstrap: [ AppComponent ]
AppComponent ...

Bootstrap
Bootstrap Array Truth #1
Every application must bootstrap at least one
component, the root application component.
Bootstrap Array Truth #2
The bootstrap array should only be used in the root
application module, AppModule.
Declarations Array

app.module.ts
Module
...
declarations: [
AppComponent,
WelcomeComponent,
Declares
ProductListComponent,
ProductDetailComponent,
ConvertToSpacesPipe,
StarComponent
Component, ]
Component
Directive, ...
Pipe

Declarations
Declarations Array Truth #1
Every component, directive, and pipe we create must
belong to one and only one Angular module.
Declarations Array Truth #2
Only declare components, directives and pipes.
Declarations Array Truth #3
Never re-declare components, directives, or pipes that
belong to another module

Module A Module B

Imports
ProductList- Star-
Exports
Component Component
Declarations
Declarations Array Truth #4
All declared components, directives, and pipes are
private by default.
Module B
They are only accessible to
other components, directives,
and pipes declared in the
Star-
same module. Component
Exports
Declarations
Declarations Array Truth #5
The Angular module provides the template resolution
environment for its component templates.
product-list.component.html star.component.ts
<pm-star ...> ...
</pm-star> @Component({
selector: 'pm-star',
template: ...
})
...
Declarations Array Truth #5
The Angular module provides the template resolution
environment for its component templates.

Module A Module B

Imports
Exports
Declarations ProductList- Star- Star-
Providers Component Component Component
Bootstrap
Exports Array

@angular
@angular
module Module
Exports module
Module
@angular
3rd party Component,
module Component
Directive,
module
Pipe

Imports
Exports
Declarations
Providers
Bootstrap
Exports Array Truth #1
Export any component, directive, or pipe if other
components need it.
Exports Array Truth #2
Re-export modules to re-export their components,
directives, and pipes.
Exports Array Truth #3
We can re-export something without importing it first.

SharedModule

Imports
FormsModule
Exports
Declarations
Providers
Bootstrap
Exports Array Truth #4
Never export a service.

AppModule

Imports ProductGuardService
Exports
Declarations
Providers
Bootstrap
Imports Array
@angular
@angular
module Module
module app.module.ts
...
3rd party Route imports: [
module module BrowserModule,
FormsModule,
Imports HttpClientModule,
RouterModule.forRoot([...])
]
...
Module
Imports Array Truth #1
Importing a module makes available any exported
components, directives, and pipes from that module.
FormsModule

Imports
Exports AppModule
Declarations
Providers
Bootstrap
Imports Array Truth #2
Only import what this module needs.
Imports Array Truth #3
Importing a module does NOT provide access to its
imported modules
FormsModule ngModel

SharedModule StarComponent

ProductList-
AppModule Component
Providers Array

app.module.ts
Module ...
providers: [ ProductGuardService ]
...

app.component.ts
...
Service
providers: [ ProductService ]
...
Imports
Exports
Declarations
Providers
Bootstrap
Providers Array Truth #1
Any service provider added to the providers array is
registered at the root of the application.

ProductModule

Imports
Exports
ProductService
Declarations
Providers
Bootstrap
Providers Array Truth #2
Don't add services to the providers array of a shared
module.
Consider building a CoreModule for services and
importing it once in the AppModule.
Providers Array Truth #3
Routing guards must be added to the providers array of
an Angular module.
BrowserModule FormsModule HttpClientModule RouterModule

AppModule

ProductDetail -
AppComponent ProductGuardService
Component

ProductList -
WelcomeComponent
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent

Providers
Bootstrap
Defining a Feature Module
CommonModule FormsModule RouterModule

AppModule ProductModule

ProductList -
ProductService
Component

ProductDetail -
ProductGuardService Component

Imports ConvertToSpaces
Exports Pipe
Declarations
Providers StarComponent
Bootstrap
Defining a Shared Module
CommonModule

ProductModule SharedModule

StarComponent

CommonModule

Imports
Exports FormsModule
Declarations
Providers
Bootstrap
Revisiting AppModule
BrowserModule

HttpClientModule RouterModule

AppModule ProductModule

AppComponent

Imports
WelcomeComponent
Exports
Declarations
Providers
Bootstrap
FormsModule

CommonModule

ProductModule

ProductList -
ProductService
Component

ProductDetail -
ProductGuardService Component

Imports ConvertToSpaces
Exports Pipe
Declarations
Providers StarComponent
Bootstrap
Application Routing Module
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { WelcomeComponent } from './home/welcome.component';

@NgModule({
imports: [
RouterModule.forRoot([
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full'},
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
])
],
exports: [ RouterModule ]
})
export class AppRoutingModule { };
Using the Routing Module
app.module.ts
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
ProductModule,
AppRoutingModule
],
declarations: [ AppComponent, WelcomeComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Using the Routing Module
app.module.ts
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
ProductModule
],
declarations: [ AppComponent, WelcomeComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Feature Routing Module
product-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { ProductListComponent } from './product-list.component';
import { ProductDetailComponent } from './product-detail.component';
import { ProductGuardService } from './product-guard.service';
@NgModule({
imports: [
RouterModule.forChild([
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', canActivate: [ ProductGuardService],
component: ProductDetailComponent }
])
],
exports: [ RouterModule ]
})
export class ProductRoutingModule { };
Using the Routing Module
product.module.ts
@NgModule({
imports: [
SharedModule,
ProductRoutingModule
],
declarations: [
ProductListComponent,
ProductDetailComponent,
ConvertToSpacesPipe
],
providers: [
ProductService,
ProductGuardService
]
})
export class ProductModule {}
Angular Module Checklist: Module Structure

Root application module (AppModule)


Feature modules
Shared module (SharedModule)
Core module (CoreModule)
Routing modules
Angular Module Checklist: NgModule Metadata

Bootstrap: Startup component(s)


Declarations: What belongs to this module
Exports: What an importing module can use
Imports: Supporting modules
Providers: Service providers
Summary What Is an Angular Module?
Angular Module Metadata
Creating a Feature Module
Defining a Shared Module
Revisiting AppModule
BrowserModule FormsModule HttpClientModule RouterModule

AppModule

ProductDetail -
AppComponent ProductGuardService
Component

ProductList -
WelcomeComponent
Component

ConvertToSpaces
Pipe
Imports
Exports
Declarations StarComponent

Providers
Bootstrap
BrowserModule

HttpClientModule RouterModule RouterModule CommonModule

AppModule ProductModule SharedModule

ProductList -
AppComponent ProductService StarComponent
Component

ProductDetail -
WelcomeComponent ProductGuardService CommonModule
Component

Imports ConvertToSpaces
FormsModule
Exports Pipe
Declarations
Providers
Bootstrap
Up Next

Angular CLI
Building, Testing, and Deploying
with the CLI

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
Module Overview
Overview ng new
ng serve
ng generate
ng test
ng build
Angular CLI Overview

A command line interface for Angular


Purpose:
- Build an Angular application
- Generate Angular files
- Execute the application
- Run unit and end to end tests
- Prepare the application for deployment
Installing the Angular CLI

npm install -g @angular/cli


Demo

ng new
Demo

ng serve
Demo

ng generate
Demo
ng test
ng e2e
Demo

ng build
Angular CLI Checklist: Commands
ng help - Displays commands and flags
ng new - Creates new Angular application
ng serve - Launches a server
ng generate - Generates file from blueprint
ng test - Runs unit tests using Karma
ng e2e - Runs end to end tests using Protractor
ng build - Compiles into an output directory
Angular CLI Checklist: ng generate
class ng g cl

component ng g c

directive ng g d

enum ng g e

guard ng g g

interface ng g i

module ng g m

pipe ng g p

service ng g s
Overview
Summary ng new
ng serve
ng generate
ng test
ng build
Learning More

"Angular CLI"
- John Papa
Final Words

Deborah Kurata
CONSULTANT | SPEAKER | AUTHOR | MVP | GDE

@deborahkurata | blogs.msmvps.com/deborahk/
What Is a Component?

Class

= + +
Properties
Component Template Metadata

Methods
Where Do We Put the Html?

Inline Template Inline Template Linked Template

template: template: ` templateUrl:


"<h1>{{pageTitle}}</h1>" './product-list.component.html'
<div>
<h1>{{pageTitle}}</h1>
<div>
My First Component
</div>
</div>
`
ES 2015
Back Ticks
When Should We Use Data Binding?

Interpolation: {{pageTitle}}

Property Binding: <img [src]='product.imageUrl'>

DOM Component
Event Binding: <button (click)='toggleImage()'>

Two-Way Binding: <input [(ngModel)]='listFilter'/>


Why Do We Need a Service?

Application
= Component
+ Component
+ Component …
Services
How Do We Build?
product-list.component.ts
import { Component } from '@angular/core';

@Component({
templateUrl: './product-list.component.html',
styleUrls: './product-list.component.css'
})
export class ProductListComponent {
pageTitle: string = 'Product List';
}
BrowserModule
How Do We Build?
HttpClientModule RouterModule RouterModule CommonModule

AppModule ProductModule SharedModule

ProductList -
AppComponent ProductService StarComponent
Component

ProductDetail -
WelcomeComponent ProductGuardService CommonModule
Component

Imports ConvertToSpaces
FormsModule
Exports Pipe
Declarations
Providers
Bootstrap
Angular CLI

ng new
ng serve
ng generate
ng test & ng e2e
ng build
Checklist

Steps and tips


Revisit as you build
Learning More
Pluralsight Courses
- "Angular: First Look"
- "Angular CLI"
- "Angular Reactive Forms"
- "Angular Routing"
- "Angular Fundamentals"

Angular Documentation
- Angular.io
GitHub Repository

https://github.com/DeborahK/Angular-GettingStarted
Angular Is …

A JavaScript framework
For building client-side applications
Using HTML, CSS and JavaScript
Angular Is …
A platform supporting
- Multiple languages (ES5, TypeScript)
- Multiple templating syntaxes (HTML,
XML)
- Multiple rendering targets (DOM, native)

Mobile Web
- Material design
- Angular Universal
- Web Workers

Native Mobile Apps


@deborahkurata

You might also like