0% found this document useful (0 votes)
90 views98 pages

Angular Merged

Uploaded by

Romero Jangre
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
90 views98 pages

Angular Merged

Uploaded by

Romero Jangre
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 98

Angular

#angular
Table of Contents
About 1

Chapter 1: Getting started with Angular 2

Remarks 2

Versions 3

Examples 5

Installation of Angular using angular-cli 6

Prerequisites: 6

To setup a new project 6

To add to an existing project 6

Running The Project Locally 6

Generating Components, Directives, Pipes and Services 7

Angular "Hello World" Program 8

Prerequisites: 8

Step 1: Creating a new project 9

Step 2: Serving the application 10

Step 3: Editing our first Angular component 10

Chapter 2: Event Emitter 13

Examples 13

Catching the event 13

Chapter 3: For Loop 15

Examples 15

NgFor - Markup For Loop 15

Chapter 4: Forms 16

Examples 16

Reactive Forms 16

app.module.ts 16

app.component.ts 16

app.component.html 17

validators.ts 18
Template Driven Forms 18

Template - signup.component.html 18

Component - signup.component.ts 19

Model - signup-request.model.ts 19

App Module - app.module.ts 20

App Component - app.component.html 20

Chapter 5: Pipes 21

Introduction 21

Examples 21

Custom Pipes 21

Multiple custom pipes 22

Chapter 6: Routing 24

Examples 24

Routing with children 24

Basic Routing 25

Chapter 7: RXJS and Observables 28

Examples 28

Wait for multiple requests 28

Basic Request 28

Chapter 8: Sharing data among components 29

Introduction 29

Remarks 29

Examples 29

Sending data from parent component to child via shared service 29

Send data from parent component to child component via data binding using @Input 30

Sending data from child to parent via @Output event emitter 31

Sending data asynchronous from parent to child using Observable and Subject 32

Credits 35
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: angular

It is an unofficial and free Angular ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official Angular.

The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com

https://riptutorial.com/ 1
Chapter 1: Getting started with Angular
Remarks
Angular (commonly referred to as "Angular 2+" or "Angular 2") is a TypeScript-based open-
source front-end web framework led by the Angular Team at Google and by a community of
individuals and corporations to address all of the parts of the developer's workflow while building
complex web applications. Angular is a complete rewrite from the same team that built AngularJS.
¹

The framework consists of several libraries, some of them core (@angular/core for example) and
some optional (@angular/animations).

You write Angular applications by composing HTML templates with Angularized markup, writing
component classes to manage those templates, adding application logic in services, and boxing
components and services in modules.

Then you launch the app by bootstrapping the root module. Angular takes over, presenting your
application content in a browser and responding to user interactions according to the instructions
you've provided.

Arguably, the most fundamental part of developing Angular applications are the components. A
component is the combination of an HTML template and a component class that controls a portion
of the screen. Here is an example of a component that displays a simple string:

src/app/app.component.ts

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

@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent {
name = 'Angular';
}

Every component begins with a @Component decorator function that takes a metadata object. The
metadata object describes how the HTML template and component class work together.

The selector property tells Angular to display the component inside a custom <my-app> tag in the
index.html file.

index.html (inside the body tag)

<my-app>Loading AppComponent content here ...</my-app>

The template property defines a message inside a <h1> header. The message starts with "Hello"

https://riptutorial.com/ 2
and ends with {{name}}, which is an Angular interpolation binding expression. At runtime, Angular
replaces {{name}} with the value of the component's name property. Interpolation binding is one of
many Angular features you'll discover in this documentation. In the example, change the
component class's name property from 'Angular' to 'World' and see what happens.

This example is written in TypeScript, a superset of JavaScript. Angular uses TypeScript because
its types make it easy to support developer productivity with tooling. Additionally, almost all
support is for TypeScript and so using plain JavaScript to write your application will be difficult
. Writing Angular code in JavaScript is possible, however; this guide explains how.

More information on the architecture of Angular can be found here

Versions

Version Release Date

5.0.0-beta.1 (Latest) 2017-07-27

4.3.2 2017-07-26

5.0.0-beta.0 2017-07-19

4.3.1 2017-07-19

4.3.0 2017-07-14

4.2.6 2017-07-08

4.2.5 2017-06-09

4.2.4 2017-06-21

4.2.3 2017-06-16

4.2.2 2017-06-12

4.2.1 2017-06-09

4.2.0 2017-06-08

4.2.0-rc.2 2017-06-01

4.2.0-rc.1 2017-05-26

4.2.0-rc.0 2017-05-19

4.1.3 2017-05-17

4.1.2 2017-05-10

https://riptutorial.com/ 3
Version Release Date

4.1.1 2017-05-04

4.1.0 2017-04-26

4.1.0-rc.0 2017-04-21

4.0.3 2017-04-21

4.0.2 2017-04-11

4.0.1 2017-03-29

4.0.0 2017-03-23

4.0.0-rc.6 2017-03-23

4.0.0-rc.5 2017-03-17

4.0.0-rc.4 2017-03-17

2.4.10 2017-03-17

4.0.0-rc.3 2017-03-10

2.4.9 2017-03-02

4.0.0-rc.2 2017-03-02

4.0.0-rc.1 2017-02-24

2.4.8 2017-02-18

2.4.7 2017-02-09

2.4.6 2017-02-03

2.4.5 2017-01-25

2.4.4 2017-01-19

2.4.3 2017-01-11

2.4.2 2017-01-06

2.4.1 2016-12-21

2.4.0 2016-12-20

2.3.1 2016-12-15

https://riptutorial.com/ 4
Version Release Date

2.3.0 2016-12-07

2.3.0-rc.0 2016-11-30

2.2.4 2016-11-30

2.2.3 2016-11-23

2.2.2 2016-11-22

2.2.1 2016-11-17

2.2.0 2016-11-14

2.2.0-rc.0 2016-11-02

2.1.2 2016-10-27

2.1.1 2016-10-20

2.1.0 2016-10-12

2.1.0-rc.0 2016-10-05

2.0.2 2016-10-05

2.0.1 2016-09-23

2.0.0 2016-09-14

2.0.0-rc.7 2016-09-13

2.0.0-rc.6 2016-08-31

2.0.0-rc.5 2016-08-09

2.0.0-rc.4 2016-06-30

2.0.0-rc.3 2016-06-21

2.0.0-rc.2 2016-06-15

2.0.0-rc.1 2016-05-03

2.0.0-rc.0 2016-05-02

Examples

https://riptutorial.com/ 5
Installation of Angular using angular-cli

This example is a quick setup of Angular and how to generate a quick example project.

Prerequisites:
• Node.js 6.9.0 or greater.
• npm v3 or greater or yarn.
• Typings v1 or greater.

Open a terminal and run the commands one by one:

npm install -g typings or yarn global add typings

npm install -g @angular/cli or yarn global add @angular/cli

The first command installs the typings library globally (and adds the typings executable to PATH).
The second installs @angular/cli globally, adding the executable ng to PATH.

To setup a new project


Navigate with the terminal to a folder where you want to set up the new project.

Run the commands:

ng new PROJECT_NAME
cd PROJECT_NAME
ng serve

That is it, you now have a simple example project made with Angular. You can now navigate to the
link displayed in terminal and see what it is running.

To add to an existing project


Navigate to the root of your current project.

Run the command:

ng init

This will add the necessary scaffolding to your project. The files will be created in the current
directory so be sure to run this in an empty directory.

Running The Project Locally


https://riptutorial.com/ 6
In order to see and interact with your application while it's running in the browser you must start a
local development server hosting the files for your project.

ng serve

If the server started successfully it should display an address at which the server is running.
Usually is this:

http://localhost:4200

Out of the box this local development server is hooked up with Hot Module Reloading, so any
changes to the html, typescript, or css, will trigger the browser to be automatically reloaded (but
can be disabled if desired).

Generating Components, Directives, Pipes


and Services
The ng generate <scaffold-type> <name> (or simply ng g <scaffold-type> <name>) command allows
you to automatically generate Angular components:

# The command below will generate a component in the folder you are currently at
ng generate component my-generated-component
# Using the alias (same outcome as above)
ng g component my-generated-component
# You can add --flat if you don't want to create new folder for a component
ng g component my-generated-component --flat
# You can add --spec false if you don't want a test file to be generated (my-generated-
component.spec.ts)
ng g component my-generated-component --spec false

There are several possible types of scaffolds angular-cli can generate:

Scaffold Type Usage

Module ng g module my-new-module

Component ng g component my-new-component

Directive ng g directive my-new-directive

Pipe ng g pipe my-new-pipe

Service ng g service my-new-service

Class ng g class my-new-class

Interface ng g interface my-new-interface

https://riptutorial.com/ 7
Scaffold Type Usage

Enum ng g enum my-new-enum

You can also replace the type name by its first letter. For example:

ng g m my-new-module to generate a new module or ng g c my-new-component to create a component.

Building/Bundling

When you are all finished building your Angular web app and you would like to install it on a web
server like Apache Tomcat, all you need to do is run the build command either with or without the
production flag set. Production will minifiy the code and optimize for a production setting.

ng build

or

ng build --prod

Then look in the projects root directory for a /dist folder, which contains the build.

If you'd like the benefits of a smaller production bundle, you can also use Ahead-of-Time template
compilation, which removes the template compiler from the final build:

ng build --prod --aot

Unit Testing

Angular provides in-built unit testing, and every item created by angular-cli generates a basic unit
test, that can be expended. The unit tests are written using jasmine, and executed through Karma.
In order to start testing execute the following command:

ng test

This command will execute all the tests in the project, and will re-execute them every time a
source file changes, whether it is a test or code from the application.

For more info also visit: angular-cli github page

Angular "Hello World" Program

Prerequisites:
Setting up the Development Environment

Before we get started, we have to setup our environment.

https://riptutorial.com/ 8
• Install Node.js and npm if they are not already on your machine.

Verify that you are running at least node 6.9.x and npm 3.x.x by running node -v and npm -v
in a terminal/console window. Older versions produce errors, but newer versions are fine.

• Install the Angular CLI globally using npm install -g @angular/cli.

Step 1: Creating a new project


Open a terminal window (or Node.js command prompt in windows).

We create a new project and skeleton application using the command:

ng new my-app

Here the ng is for Angular. We get a file structure something like this.

https://riptutorial.com/ 9
There are lots of files. We need not worry about all of them now.

Step 2: Serving the application


We launch our application using following command:

ng serve

We may use a flag -open( or simply -o) which will automatically open our browser on
http://localhost:4200/

ng serve --open

Navigate browser to the address http://localhost:4200/. It looks something like this:

Step 3: Editing our first Angular component

https://riptutorial.com/ 10
The CLI created the default Angular component for us. This is the root component and it is named
app-root. One can find it in ./src/app/app.component.ts.

Open the component file and change the title property from Welcome to app!! to Hello World. The
browser reloads automatically with the revised title.

Original Code : Notice the title = 'app';

Modified Code : Value of title is changed.

Similarly there is a change in ./src/app/app.component.html.

Original HTML

Modified HTML

https://riptutorial.com/ 11
Notice that the value of title from the ./src/app/app.component.ts will be displayed. The browser
reloads automatically when the changes are done. It looks something like this.

To find more on the topic, visit this link here.

Read Getting started with Angular online: https://riptutorial.com/angular/topic/9754/getting-started-


with-angular

https://riptutorial.com/ 12
Chapter 2: Event Emitter
Examples
Catching the event

Create a service-

import {EventEmitter} from 'angular2/core';


export class NavService {
navchange: EventEmitter<number> = new EventEmitter();
constructor() {}
emitNavChangeEvent(number) {
this.navchange.emit(number);
}
getNavChangeEmitter() {
return this.navchange;
}
}

Create a component to use the service-

import {Component} from 'angular2/core';


import {NavService} from '../services/NavService';

@Component({
selector: 'obs-comp',
template: `obs component, item: {{item}}`
})
export class ObservingComponent {
item: number = 0;
subscription: any;
constructor(private navService:NavService) {}
ngOnInit() {
this.subscription = this.navService.getNavChangeEmitter()
.subscribe(item => this.selectedNavItem(item));
}
selectedNavItem(item: number) {
this.item = item;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}

@Component({
selector: 'my-nav',
template:`
<div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div>
<div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>
`,
})
export class Navigation {
item = 1;
constructor(private navService:NavService) {}

https://riptutorial.com/ 13
selectedNavItem(item: number) {
console.log('selected nav item ' + item);
this.navService.emitNavChangeEvent(item);
}
}

Read Event Emitter online: https://riptutorial.com/angular/topic/9828/event-emitter

https://riptutorial.com/ 14
Chapter 3: For Loop
Examples
NgFor - Markup For Loop

The NgFor directive instantiates a template once per item from an iterable. The context for each
instantiated template inherits from the outer context with the given loop variable set to the current
item from the iterable.

To customize the default tracking algorithm, NgFor supports trackBy option. trackBy takes a
function which has two arguments: index and item. If trackBy is given, Angular tracks changes by
the return value of the function.

<li *ngFor="let item of items; let i = index; trackBy: trackByFn">


{{i}} - {{item.name}}
</li>

Additional Options: NgFor provides several exported values that can be aliased to local
variables:

• index will be set to the current loop iteration for each template context.
• first will be set to a boolean value indicating whether the item is the first one in the iteration.
• last will be set to a boolean value indicating whether the item is the last one in the iteration.
• even will be set to a boolean value indicating whether this item has an even index.
• odd will be set to a boolean value indicating whether this item has an odd index.

Read For Loop online: https://riptutorial.com/angular/topic/9826/for-loop

https://riptutorial.com/ 15
Chapter 4: Forms
Examples
Reactive Forms

app.module.ts
Add these into your app.module.ts file to use reactive forms

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


import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';

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

app.component.ts

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


import template from './app.component.html';
import { FormGroup,FormBuilder,Validators } from '@angular/forms';
import { matchingPasswords } from './validators';

@Component({
selector: 'app',
template
})
export class AppComponent implements OnInit {
addForm: FormGroup;

constructor(private formBuilder: FormBuilder) {


}

ngOnInit() {
this.addForm = this.formBuilder.group({
username: ['', Validators.required],
email: ['', Validators.required],
role: ['', Validators.required],
password: ['', Validators.required],
password2: ['', Validators.required]
}, { validator: matchingPasswords('password', 'password2') });

https://riptutorial.com/ 16
};

addUser() {
if (this.addForm.valid) {
var adduser = {
username: this.addForm.controls['username'].value,
email: this.addForm.controls['email'].value,
password: this.addForm.controls['password'].value,
profile: {
role: this.addForm.controls['role'].value,
name: this.addForm.controls['username'].value,
email: this.addForm.controls['email'].value
}
};

console.log(adduser);// adduser var contains all our form values. store it where
you want
this.addForm.reset();// this will reset our form values to null
}
}

app.component.html

<div>
<form [formGroup]="addForm">
<input
type="text"
placeholder="Enter username"
formControlName="username" />

<input
type="text"
placeholder="Enter Email Address"
formControlName="email"/>

<input
type="password"
placeholder="Enter Password"
formControlName="password" />

<input
type="password"
placeholder="Confirm Password"
name="password2"
formControlName="password2" />

<div class='error' *ngIf="addForm.controls.password2.touched">


<div
class="alert-danger errormessageadduser"
*ngIf="addForm.hasError('mismatchedPasswords')">
Passwords do not match
</div>
</div>
<select name="Role" formControlName="role">
<option value="admin" >Admin</option>
<option value="Accounts">Accounts</option>
<option value="guest">Guest</option>

https://riptutorial.com/ 17
</select>
<br/>
<br/>
<button type="submit" (click)="addUser()">
<span>
<i class="fa fa-user-plus" aria-hidden="true"></i>
</span>
Add User
</button>
</form>
</div>

validators.ts

export function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {


return (group: ControlGroup): {
[key: string]: any
} => {
let password = group.controls[passwordKey];
let confirmPassword = group.controls[confirmPasswordKey];

if (password.value !== confirmPassword.value) {


return {
mismatchedPasswords: true
};
}
}
}

Template Driven Forms

Template - signup.component.html

<form #signUpForm="ngForm" (ngSubmit)="onSubmit()">

<div class="title">
Sign Up
</div>

<div class="input-field">
<label for="username">username</label>
<input
type="text"
pattern="\w{4,20}"
name="username"
required="required"
[(ngModel)]="signUpRequest.username" />
</div>

<div class="input-field">
<label for="email">email</label>
<input
type="email"
pattern="^\S+@\S+$"
name="email"
required="required"

https://riptutorial.com/ 18
[(ngModel)]="signUpRequest.email" />
</div>

<div class="input-field">
<label for="password">password</label>
<input
type="password"
pattern=".{6,30}"
required="required"
name="password"
[(ngModel)]="signUpRequest.password" />
</div>

<div class="status">
{{ status }}
</div>

<button [disabled]="!signUpForm.form.valid" type="submit">


<span>Sign Up</span>
</button>

</form>

Component - signup.component.ts

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

import { SignUpRequest } from './signup-request.model';

@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent {

status: string;
signUpRequest: SignUpRequest;

constructor() {
this.signUpRequest = new SignUpRequest();
}

onSubmit(value, valid) {
this.status = `User ${this.signUpRequest.username} has successfully signed up`;
}

Model - signup-request.model.ts

export class SignUpRequest {

constructor(
public username: string="",
public email: string="",

https://riptutorial.com/ 19
public password: string=""
) {}

App Module - app.module.ts

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


import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

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


import { SignupComponent } from './signup/signup.component';

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

App Component - app.component.html

<app-signup></app-signup>

Read Forms online: https://riptutorial.com/angular/topic/9825/forms

https://riptutorial.com/ 20
Chapter 5: Pipes
Introduction
Pipes are very similar to filters in AngularJS in that they both help to transform the data into a
specified format.The pipe character | is used to apply pipes in Angular.

Examples
Custom Pipes

my.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'myPipe'})
export class MyPipe implements PipeTransform {

transform(value:any, args?: any):string {


let transformedValue = value; // implement your transformation logic here
return transformedValue;
}

my.component.ts

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

@Component({
selector: 'my-component',
template: `{{ value | myPipe }}`
})
export class MyComponent {

public value:any;

my.module.ts

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


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

import { MyComponent } from './my.component';


import { MyPipe } from './my.pipe';

@NgModule({
imports: [
BrowserModule,
],

https://riptutorial.com/ 21
declarations: [
MyComponent,
MyPipe
],
})
export class MyModule { }

Multiple custom pipes

Having different pipes is a very common case, where each pipe does a different thing. Adding
each pipe to each component may become a repetitive code.

It is possible to bundle all frequently used pipes in one Module and import that new module in any
component needs the pipes.

breaklines.ts

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


/**
* pipe to convert the \r\n into <br />
*/
@Pipe({ name: 'br' })
export class BreakLine {
transform(value: string): string {
return value == undefined ? value :
value.replace(new RegExp('\r\n', 'g'), '<br />')
.replace(new RegExp('\n', 'g'), '<br />');
}
}

uppercase.ts

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


/**
* pipe to uppercase a string
*/
@Pipe({ name: 'upper' })
export class Uppercase{
transform(value: string): string {
return value == undefined ? value : value.toUpperCase( );
}
}

pipes.module.ts

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


import { BreakLine } from './breakLine';
import { Uppercase} from './uppercase';

@NgModule({
declarations: [
BreakLine,
Uppercase
],
imports: [

https://riptutorial.com/ 22
],
exports: [
BreakLine,
Uppercase
]
,
})
export class PipesModule {}

my.component.ts

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

@Component({
selector: 'my-component',
template: `{{ value | upper | br}}`
})
export class MyComponent {

public value: string;

my.module.ts

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


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

import { MyComponent } from './my.component';


import { PipesModule} from './pipes.module';

@NgModule({
imports: [
BrowserModule,
PipesModule,
],
declarations: [
MyComponent,
],
})

Read Pipes online: https://riptutorial.com/angular/topic/9824/pipes

https://riptutorial.com/ 23
Chapter 6: Routing
Examples
Routing with children

I found this to be the way to properly nest children routes inside the app.routing.ts or
app.module.ts file (depending on your preference). This approach works when using either
WebPack or SystemJS.

The example below shows routes for home, home/counter, and home/counter/fetch-data. The first
and last routes being examples of redirects. Finally at the end of the example is a proper way to
export the Route to be imported in a separate file. For ex. app.module.ts

To further explain, Angular requires that you have a pathless route in the children array that
includes the parent component, to represent the parent route. It's a little confusing but if you think
about a blank URL for a child route, it would essentially equal the same URL as the parent route.

import { NgModule } from "@angular/core";


import { RouterModule, Routes } from "@angular/router";

import { HomeComponent } from "./components/home/home.component";


import { FetchDataComponent } from "./components/fetchdata/fetchdata.component";
import { CounterComponent } from "./components/counter/counter.component";

const appRoutes: Routes = [


{
path: "",
redirectTo: "home",
pathMatch: "full"
},
{
path: "home",
children: [
{
path: "",
component: HomeComponent
},
{
path: "counter",
children: [
{
path: "",
component: CounterComponent
},
{
path: "fetch-data",
component: FetchDataComponent
}
]
}
]
},
{

https://riptutorial.com/ 24
path: "**",
redirectTo: "home"
}
];

@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }

Great Example and Description via Siraj

Basic Routing

Router enables navigation from one view to another based on user interactions with the
application.

Following are the steps in implementing basic routing in Angular -

NOTE: Ensure you have this tag:

<base href='/'>

as the first child under your head tag in your index.html file. This element states that your app
folder is the application root. Angular would then know how to organize your links.

1. Check if you are pointing to the correct/latest routing dependencies in package.json (using
the latest version of Angular) and that you already did an npm install -

"dependencies": {
"@angular/router": "^4.2.5"
}

2. Define the route as per its interface definition:

interface Route {
path?: string;
pathMatch?: string;
component?: Type<any>;
}

3. In a routing file (routes/app.routing.ts), import all the components which you need to
configure for different routing paths. Empty path means that view is loaded by default. ":" in
the path indicates dynamic parameter passed to the loaded component.

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


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

https://riptutorial.com/ 25
import { BarDetailComponent } from '../components/bar-detail.component';
import { DashboardComponent } from '../components/dashboard.component';
import { LoginComponent } from '../components/login.component';
import { SignupComponent } from '../components/signup.component';

export const APP_ROUTES: Routes = [


{ path: '', pathMatch: 'full', redirectTo: 'login' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'bars/:id', component: BarDetailComponent },
{ path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent }
];
export const APP_ROUTING: ModuleWithProviders = RouterModule.forRoot(APP_ROUTES);

4. In your app.module.ts, place this under @NgModule([]) under imports:

// Alternatively, just import 'APP_ROUTES


import {APP_ROUTING} from '../routes/app.routing.ts';
@NgModule([
imports: [
APP_ROUTING
// Or RouterModule.forRoot(APP_ROUTES)
]
])

5. Load/display the router components based on path accessed. The <router-outlet>directive is


used to tell angular where to load the component.

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

@Component({
selector: 'demo-app',
template: `
<div>
<router-outlet></router-outlet>
</div>
`
})
export class AppComponent {}

6. Link the other routes. By default, RouterOutlet will load the component for which empty path
is specified in the Routes. RouterLink directive is used with html anchor tag to load the
components attached to routes. RouterLink generates the href attribute which is used to
generate links. For example:

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

@Component({
selector: 'demo-app',
template: `
<a [routerLink]="['/login']">Login</a>
<a [routerLink]="['/signup']">Signup</a>
<a [routerLink]="['/dashboard']">Dashboard</a>
<div>
<router-outlet></router-outlet>

https://riptutorial.com/ 26
</div>
`
})
export class AnotherComponent { }

Now, we are good with routing to static paths. RouterLink supports dynamic path too by passing
extra parameters along with the path.

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

@Component({
selector: 'demo-app',
template: `
<ul>
<li *ngFor="let bar of bars | async">
<a [routerLink]="['/bars', bar.id]">
{{bar.name}}
</a>
</li>
</ul>
<div>
<router-outlet></router-outlet>
</div>
`
})
export class SecondComponent { }

RouterLinktakes an array where the first parameter is the path for routing and subsequent
elements are for the dynamic routing parameters.

Read Routing online: https://riptutorial.com/angular/topic/9827/routing

https://riptutorial.com/ 27
Chapter 7: RXJS and Observables
Examples
Wait for multiple requests

One common scenario is to wait for a number of requests to finish before continuing. This can be
accomplished using the forkJoin method.

In the following example, forkJoin is used to call two methods that return Observables. The callback
specified in the .subscribe method will be called when both Observables complete. The
parameters supplied by .subscribe match the order given in the call to .forkJoin. In this case, first
posts then tags.

loadData() : void {
Observable.forkJoin(
this.blogApi.getPosts(),
this.blogApi.getTags()
).subscribe((([posts, tags]: [Post[], Tag[]]) => {
this.posts = posts;
this.tags = tags;
}));
}

Basic Request

The following example demonstrates a simple HTTP GET request. http.get() returns an
Observable which has the method subscribe. This one appends the returned data to the posts array.

var posts = []

getPosts(http: Http): {
this.http.get(`https://jsonplaceholder.typicode.com/posts`)
.subscribe(response => {
posts.push(response.json());
});
}

Read RXJS and Observables online: https://riptutorial.com/angular/topic/9829/rxjs-and-


observables

https://riptutorial.com/ 28
Chapter 8: Sharing data among components
Introduction
The objective of this topic is to create simple examples of several ways data can be shared
between components via data binding and shared service.

Remarks
There are always many of ways of accomplishing one task in programming. Please feel free to edit
current examples or add some of your own.

Examples
Sending data from parent component to child via shared service

service.ts:

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

@Injectable()
export class AppState {

public mylist = [];

parent.component.ts:

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


import { AppState } from './shared.service';

@Component({
selector: 'parent-example',
templateUrl: 'parent.component.html',
})
export class ParentComponent {
mylistFromParent = [];

constructor(private appState: AppState){


this.appState.mylist;
}

add() {
this.appState.mylist.push({"itemName":"Something"});
}

parent.component.html:

https://riptutorial.com/ 29
<p> Parent </p>
<button (click)="add()">Add</button>
<div>
<child-component></child-component>
</div>

child.component.ts:

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


import { AppState } from './shared.service';

@Component({
selector: 'child-component',
template: `
<h3>Child powered by shared service</h3>
{{mylist | json}}
`,
})
export class ChildComponent {
mylist: any;

constructor(private appState: AppState){


this.mylist = this.appState.mylist;
}

Send data from parent component to child component via data binding using
@Input

parent.component.ts:

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

@Component({
selector: 'parent-example',
templateUrl: 'parent.component.html',
})

export class ParentComponent {


mylistFromParent = [];

add() {
this.mylistFromParent.push({"itemName":"Something"});
}

parent.component.html:

<p> Parent </p>


<button (click)="add()">Add</button>

<div>
<child-component [mylistFromParent]="mylistFromParent"></child-component>
</div>

https://riptutorial.com/ 30
child.component.ts:

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

@Component({
selector: 'child-component',
template: `
<h3>Child powered by parent</h3>
{{mylistFromParent | json}}
`,
})

export class ChildComponent {


@Input() mylistFromParent = [];
}

Sending data from child to parent via @Output event emitter

event-emitter.component.ts

import { Component, OnInit, EventEmitter, Output } from '@angular/core';

@Component({
selector: 'event-emitting-child-component',
template: `<div *ngFor="let item of data">
<div (click)="select(item)">
{{item.id}} = {{ item.name}}
</div>
</div>
`
})

export class EventEmitterChildComponent implements OnInit{

data;

@Output()
selected: EventEmitter<string> = new EventEmitter<string>();

ngOnInit(){
this.data = [ { "id": 1, "name": "Guy Fawkes", "rate": 25 },
{ "id": 2, "name": "Jeremy Corbyn", "rate": 20 },
{ "id": 3, "name": "Jamie James", "rate": 12 },
{ "id": 4, "name": "Phillip Wilson", "rate": 13 },
{ "id": 5, "name": "Andrew Wilson", "rate": 30 },
{ "id": 6, "name": "Adrian Bowles", "rate": 21 },
{ "id": 7, "name": "Martha Paul", "rate": 19 },
{ "id": 8, "name": "Lydia James", "rate": 14 },
{ "id": 9, "name": "Amy Pond", "rate": 22 },
{ "id": 10, "name": "Anthony Wade", "rate": 22 } ]
}

select(item) {
this.selected.emit(item);

https://riptutorial.com/ 31
event-receiver.component.ts:

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

@Component({
selector: 'event-receiver-parent-component',
template: `<event-emitting-child-component (selected)="itemSelected($event)">
</event-emitting-child-component>
<p *ngIf="val">Value selected</p>
<p style="background: skyblue">{{ val | json}}</p>`
})

export class EventReceiverParentComponent{


val;

itemSelected(e){
this.val = e;
}
}

Sending data asynchronous from parent to child using Observable and


Subject

shared.service.ts:

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


import { Headers, Http } from '@angular/http';

import 'rxjs/add/operator/toPromise';

import { Observable } from 'rxjs/Observable';


import { Observable } from 'rxjs/Rx';
import {Subject} from 'rxjs/Subject';

@Injectable()
export class AppState {

private headers = new Headers({'Content-Type': 'application/json'});


private apiUrl = 'api/data';

// Observable string source


private dataStringSource = new Subject<string>();

// Observable string stream


dataString$ = this.dataStringSource.asObservable();

constructor(private http: Http) { }

public setData(value) {
this.dataStringSource.next(value);
}

fetchFilterFields() {
console.log(this.apiUrl);
return this.http.get(this.apiUrl)
.delay(2000)
.toPromise()

https://riptutorial.com/ 32
.then(response => response.json().data)
.catch(this.handleError);
}

private handleError(error: any): Promise<any> {


console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}

parent.component.ts:

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


import 'rxjs/add/operator/toPromise';
import { AppState } from './shared.service';

@Component({
selector: 'parent-component',
template: `
<h2> Parent </h2>
<h4>{{promiseMarker}}</h4>

<div>
<child-component></child-component>
</div>
`
})
export class ParentComponent implements OnInit {

promiseMarker = "";

constructor(private appState: AppState){ }

ngOnInit(){
this.getData();
}

getData(): void {
this.appState
.fetchFilterFields()
.then(data => {
// console.log(data)
this.appState.setData(data);
this.promiseMarker = "Promise has sent Data!";
});
}

child.component.ts:

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


import { AppState } from './shared.service';

@Component({
selector: 'child-component',
template: `

https://riptutorial.com/ 33
<h3>Child powered by shared service</h3>
{{fields | json}}
`,
})
export class ChildComponent {
fields: any;

constructor(private appState: AppState){


// this.mylist = this.appState.get('mylist');

this.appState.dataString$.subscribe(
data => {
// console.log("Subs to child" + data);
this.fields = data;
});

Read Sharing data among components online: https://riptutorial.com/angular/topic/10836/sharing-


data-among-components

https://riptutorial.com/ 34
Credits
S.
Chapters Contributors
No

aholtry, Anup Kumar Gupta, BogdanC, Community, daddycool,


Getting started with
1 Edric, Fahad Nisar, Faisal, Hendrik Brummermann, Philipp Kief,
Angular
Tom

2 Event Emitter aholtry

3 For Loop aholtry

4 Forms aholtry, Saka7

5 Pipes aholtry, Amr ElAdawy

6 Routing 0mpurdy, aholtry, Edric

RXJS and
7 aholtry
Observables

Sharing data among


8 0mpurdy, BogdanC, JGFMK, Nehal
components

https://riptutorial.com/ 35
ANGULARJS
CHEAT SHEET
AngularJS is an extensible and exciting new JavaScript MVC framework developed by Google for
building well-designed, structured and interactive single-page applications (SPA). It lays strong
emphasis on Testing and Development best practices such as templating and declarative bi-directional
data binding.

This cheat sheet co-authored by Ravi Kiran and Suprotim Agarwal, aims at providing a quick reference to
the most commonly used features in AngularJS. It will also make you quickly productive with Angular.

This article is from the Free DNC Magazine for .Net and JavaScript developers. Subscribe to
this magazine for free (using only your email address) and download all the editions.

BEGINNER

01 Important AngularJS Components and their 02 Bootstrapping AngularJS application:


usage:
Bootstrapping in HTML:
• angular.module() defines a module <div ng-app=”moduleName”></div>

• Module.controller() defines a controller


Manual bootstrapping:
• Module.directive() defines a directive
angular.bootstrap(document,[“moduleName”])
• Module.filter() defines a filter
• Module.service() or Module.factory() or
Module.provider() defines a service
• Module.value() defines a service from an existing
03 Expressions:

object Module {{ 4+5 }} -> yields 9


• ng-app attribute sets the scope of a module
• ng-controller attribute applies a controller to the {{ name }} -> Binds value of name from current
view scope and watches for changes to name
• $scope service passes data from controller to the
view {{ ::name }} -> Binds value of name from current
• $filter service uses a filter scope and doesn’t watch for change (Added in
• ng-app attribute sets the scope of the module AngularJS 1.3)

www.dotnetcurry.com/magazine 01
04 Module: svc.addCity = function(city){
cities.push(city);
};
Create a module named myModule1 that depends on
myModule2 and myModule2: svc.getCities = function(){
angular.module(“myModule1”,[“myModule2”, return cities;
“myModule2”]) }
});
Get reference to the module myModule1
angular.module(“myModule1”) The members added to instance of the service are visible to the
outside world. Others are private to the service. Services are

05 Defining a Controller and using it: singletons, i.e. only one instance of the service is created in the
lifetime of an AngularJS application.
i. With $scope:

angular.module(“myModule”). 07
Factory:
controller(“SampleController”,
angular.module(“myModule”).
function($scope,){
factory(“sampleFactory”, function(){
//Members to be used in view for binding
var cities = [“New Delhi”, “Mumbai”,
$scope.city=”Hyderabad”;
“Kolkata”, “Chennai”];
});
function addCity(city){cities.push(city);}
function getCities(){return cities;}
In the view: return{
getCities: getCities,
<div ng-controller=”SampleController”> addCity:addCity
<!-- Template of the view with binding };
expressions using members of $scope --> });
<div>{{city}}</div>
</div>
A factory is a function that returns an object. The members
that are not added to the returning object, remain private
ii. Controller as syntax:
to the factory. The factory function is executed once and the
result is stored. Whenever an application asks for a factory, the
angular.module(“myModule”).
application returns the same object. This behavior makes the
controller(“SampleController”, function(){
var controllerObj = this; factory a singleton.
//Members to be used on view for binding
controllerObj.city=”Hyderabad”;
}); 08
Value:

angular.module(“myModule”).value(“sampleValue”, {
In the view:
cities : [“New Delhi”, “Mumbai”, “Kolkata”,
“Chennai”],
<div ng-controller=”SampleController as ctrl”>
addCity: function(city){cities.push(city);},
<div>{{ctrl.city}}</div>
getCities: function(){return cities;}
</div>
});

06 Defining a Service: A value is a simple JavaScript object. It is created just once, so


value is also a singleton. Values can’t contain private members.
angular.module(“myModule”).
All members of a value are public.
service(“sampleService”, function(){
var svc = this;
var cities=[“New Delhi”, “Mumbai”,
“Kolkata”, “Chennai”];

02 www.dotnetcurry.com/magazine
09 Constant: application. Services, Factories and values are not available
for config block as they are not created by this time. Only
angular.module(“myModule”). providers and constants are accessible inside the config block.
constant(“sampleConstant”,{pi: Math.PI}); Config block is executed only once in the lifetime of an Angular
application.
A constant is also like a value. The difference is, a constant can
be injected into config blocks, but a value cannot be injected.
12 Run block:

10 Provider: angular.module(“myModule”).run(function(<any
services, factories>){
angular.module(“myModule”). console.log(“Application is configured. Now inside run
provider(“samplePrd”, function(){ block”);
this.initCities = function(){ });
console.log(“Initializing Cities…”);
}; Run block is used to initialize certain values for further
use, register global events and anything that needs to run at
this.$get = function(){
the beginning of the application. Run block is executed after
var cities = [“New Delhi”, “Mumbai”,
“Kolkata”, “Chennai”]; config block, and it gets access to services, values and factories.
function addCity(city){ Run block is executed only once in the lifetime of an Angular
cities.push(city); application.
}
function getCities(){return cities;}
return{ getCities: getCities,addCity:addCity 13 Filters:
};
} angular.module(“myModule”).
}); filter(“dollarToRupeee”, function(){
return function(val){
return “Rs. “ + val * 60;
A provider is a low level recipe. The $get() method of the };
provider is registered as a factory. Providers are available });
to config blocks and other providers. Once application
configuration phase is completed, access to providers is Usage:
prevented. <span>{{price | dollarToRupee}}</span>

After the configuration phase, the $get() method of the Filters are used to extend the behavior of binding expressions
providers are executed and they are available as factories. and directives. In general, they are used to format values or to
Services, Factories and values are wrapped inside provider with apply certain conditions. They are executed whenever the value
$get() method returning the actual logic implemented inside bound in the binding expression is updated.
the provider.

14 Directives:
11 Config block:
myModule.directive(“directiveName”, function
angular.module(“myModule”).config(function (injectables) {
(samplePrdProvider, sampleConstant){ return {
samplePrdProvider.init(); restrict: “A”,
console.log(sampleConstant.pi); template: “<div></div>”,
}); templateUrl: “directive.html”,
replace: false,
transclude: false,
Config block runs as soon as a module is loaded. As the name
scope: false,
itself suggests, the config block is used to configure the

www.dotnetcurry.com/magazine 03
require: [“someOtherDirective”], of the current directive.
controller: function($scope, $element,
$attrs, $transclude, otherInjectables) { ... },
• controller: Controller for the directive. Can be used to
link: function postLink(scope, iElement,
manipulate values on scope or as an API for the current
iAttrs) { ... },
priority: 0, directive or a directive requiring the current directive
terminal: false,
compile: function compile(tElement, tAttrs, • priority: Sets priority of a directive. Default value is 0.
transclude) { Directive with higher priority value is executed before a
return {
directive with lower priority
pre: function preLink(scope, iElement,
iAttrs, controller) { ... },
post: function postLink(scope, • terminal: Used with priority. If set to true, it stops execution
iElement, iAttrs, controller) { ... } of directives with lower priority. Default is false
}
} • link: A function that contains core logic of the directive.
};
It is executed after the directive is compiled. Gets access
});
to scope, element on which the directive is applied (jqLite
object), attributes of the element containing the directive and
Directives add the capability of extending HTML. They are the
controller object. Generally used to perform DOM manipulation
most complex and the most important part of AngularJS. A
and handling events
directive is a function that returns a special object, generally
termed as Directive Definition Object. The Directive Definition
• compile: A function that runs before the directive is compiled.
Object is composed of several options as shown in the above
Doesn’t have access to scope as the scope is not created yet.
snippet. Following is a brief note on them:
Gets an object of the element and attributes. Used to perform
DOM of the directive before the templates are compiled and
• restrict: Used to specify how a directive can be used. Possible
before the directive is transcluded. It returns an object with two
values are: E (element), A (Attribute), C (Class) and M (Comment).
link functions:
Default value is A

o pre link: Similar to the link function, but it is executed


• template: HTML template to be rendered in the directive
before the directive is compiled. By this time, transclusion is
applied
• templateUrl: URL of the file containing HTML template of the
element
o post link: Same as link function mentioned above

• replace: Boolean value denoting if the directive element is to


be replaced by the template. Default value is false 15
. Most used built-in directives:

• transclude: Boolean value that says if the directive should • ng-app: To bootstrap the application
preserve the HTML specified inside directive element after
rendering. Default is false • ng-controller: To set a controller on a view

• scope: Scope of the directive. It may be same as the scope of • ng-view: Indicates the portion of the page to be
surrounding element (default or when set to false), inherited updated when route changes
from scope of the surrounding element (set to true) or an
isolated scope (set to {}) • ng-show / ng-hide: Shows/hides the content within
the directive based on boolean equivalent of value
• require: A list of directive that the current directive needs. assigned
Current directive gets access to controller of the required
directive. An object of the controller is passed into link function • ng-if: Places or removes the DOM elements under

04 www.dotnetcurry.com/magazine
this directive based on boolean equivalent of value 16 AngularJS Naming Conventions
assigned
• While naming a file say an authentication controller,
end it with the object suffix. For eg: an authentication
• ng-model: Enables two-way data binding on any
controller can be renamed as auth–controller.js.
input controls and sends validity of data in the input
Similar service can be called as auth-service.js,
control to the enclosing form
directive as auth-directive.js and a filter as auth-filter.js

• ng-class: Provides an option to assign value of • Create meaningful & short lower case file names that also
a model to CSS, conditionally apply styles and use reflect the folder structure. For eg: if we have a login controller
multiple models for CSS declaratively inside the login folder which is used for creating users, call it
login-create-controller.js
• ng-repeat: Loops through a list of items and copies
the HTML for every record in the collection • Similar a testing naming convention that you could follow
is if the filename is named as login-directive.js, call its test file
• ng-options: Used with HTML select element to counterpart as login-directive_test.js. Similarly a test file for
render options based on data in a collection login-service.js can be called as login-service_test.js
Use a workflow management tool like Yeoman plugin for
• ng-href: Assigns a model as hyperlink to an anchor Angular that automates a lot of these routines and much more
element for you. Also look at ng-boilerplate to get an idea of the project
and directory structure.
• ng-src: Assigns a model to source of an image
element 17 Dependency Injection:

• ng-click: To handle click event on any element AngularJS has a built-in dependency injector that keeps track
of all components (services, values, etc.) and returns instances
• ng-change: Requires ng-model to be present of needed components using dependency injection. Angular’s
along with it. Calls the event handler or evaluates the dependency injector works based on names of the components.
assigned expression when there is a change to value
of the model A simple case of dependency injection:

• ng-form: Works same as HTML form and allows myModule.controller(“MyController”, function($scope,


$window, myService){
nesting of forms
});

• ng-non-bindable: Prevents AngularJS from


Here, $scope, $window and myService are passed into the
compiling or binding the contents of the current DOM
controller through dependency injection. But the above code
element
will break when the code is minified. Following approach solves
it:
• ng-repeat-start and ng-repeat-end: Repeats top-level
attributes
myModule.controller(“MyController”, [“$scope”,
“$window”, “myService”,
• ng-include: Loads a partial view function($scope, $window, myService){
}]);
• ng-init: Used to evaluate an expression in the current scope

• ng-switch conditionally displays elements

• ng-cloak to prevent Angular HTML to load before


bindings are applied.

www.dotnetcurry.com/magazine 05
18 Routes 21 Some useful utility functions

Routes in AngularJS application are defined using • angular.copy - Creates a deep copy of source
$routeProvider. We can define a list of routes and set one of
the routes as default using otherwise() method; this route • angular.extend - Copy methods and properties from one
will respond when the URL pattern doesn’t match any of the object to another
configured patterns.
• angular.element - Wraps a raw DOM element or HTML string
as a jQuery element

19 Registering routes: • angular.equals - Determines if two objects or two values are


equivalent
myModule.config(function($routeProvider){
$routeProvider.when(“/home”, • angular.forEach - Enumerate the content of a collection
{templateUrl:”templates/home.html”,
controller: “HomeController”}) • angular.toJson - Serializes input into a JSON-formatted string
.when(“/details/:id”, {template:
“templates/details.html”,
• angular.fromJson - Deserializes a JSON string
controller:”ListController”})
.otherwise({redirectTo: “/home”});
}); • angular.identity - Returns its first argument

• angular.isArray - Determines if a reference is an Array

• angular.isDate - Determines if a value is a date


20 Registering services:
• angular.isDefined - Determines if a reference is defined
Angular provides us three ways to create and register our
own Services – using Factory, Service, and Provider. They are all • angular.isElement - Determines if a reference is a DOM
used for the same purpose. Here’s the syntax for all the three: element

Service: module.service( ‘serviceName’, function ); • angular.isFunction - Determines if a reference is a Function


Factory: module.factory( ‘factoryName’, function );
Provider: module.provider( ‘providerName’, function ); • angular.isNumber - Determines if a reference is a Number

The basic difference between a service and a factory is that • angular.isObject - Determines if a reference is an Object
service uses the constructor function instead of returning a
factory function. This is similar to using the new operator. So • angular.isString - Determines if a reference is a String
you add properties to ‘this’ and the service returns ‘this’.

• angular.isUndefined - Determines if a reference is undefined


With Factories, you create an object, add properties to it and
then return the same object. This is the most common way of • angular.lowercase - Converts the specified string to lowercase
creating Services.

• angular.uppercase - Converts the specified string to


If you want to create module-wide configurable services uppercase
which can be configured before being injected inside other
components, use Provider. The provider uses the $get function
to expose its behavior and is made available via dependency
injection.

06 www.dotnetcurry.com/magazine
22 $http:

$http is Angular’s wrapper around XmlHttpRequest. It provides


a set of high level APIs and a low level API to talk to REST
services. Each of the API methods return $q promise object.

Following are the APIs exposed by $http:

• $http.$get(url): Sends an HTTP GET request to the URL


specified

• $http.post(url, dataToBePosted): Sends an HTTP POST


request to the URL specified

• $http.put(url, data): Sends an HTTP PUT request to the URL


specified

• $http.patch(url, data): Sends an HTTP PATCH request to the


URL specified

• $http.delete(url): Sends an HTTP DELETE request to the URL


specified

• $http(config): It is the low level API. Can be used to send


any of the above request types and we can also specify other
properties to the request. Following are the most frequently
used config options:

o method: HTTP method as a string, e.g., ‘GET’, ‘POST’, ‘PUT’, etc.


o url: Request URL
o data: Data to be sent along with request
o headers: Header parameters to be sent along with the
request
o cache: caches the response when set to true

Following is a small snippet showing usage of $http:

$http.get(‘/api/data’).then(function(result){
return result.data;
}, function(error){
return error;
});

www.dotnetcurry.com/magazine 07
• $q.reject(reason) - Creates a promise that is resolved as
INTERMEDIATE - ADVANCED
rejected with the specified reason. The return value ensures
that the promise continues to the next error handler instead of
23 Manage Dependencies a success handler.

Use a package management tool like Bower (bower.io/) to • deferredObject.resolve - Resolves the derived promise with
manage and update third-party web dependencies in your the value
project. It is as simple as installing bower using npm install
bower; then listing all the dependent libraries and versions in a • deferredObject.reject - Rejects the derived promise with the
Bower package definition file called bowerconfig.json and lastly reason and triggers the failure handler in the promise.
run bower install or bower update in your project to get the
latest versions of any web dependencies in your project.
27 Manipulating $scope

24 Using AngularJS functions


Do not make changes to the $scope from the View. Instead do it
using a Controller. Let’s see an example. The following piece of
Wherever possible, use AngularJS versions of JavaScript
code controls the state of the dialog property directly from the
functionality. So instead of setInterval, use the $interval
ng-click directive.
service. Similarly instead of setTimeout use the $timeout
service. It becomes easier to mock them or write unit tests . Also
<div>
make sure to clean it up when you have no use for it. Use the <button ng-click=”response = false”>Close Dialog
$destroy event to do so: </button>
</div>
$scope.$on(“$destroy”, function (event) {
$timeout.cancel(timerobj); Instead we can do this in a Controller and let it control the
});
state of the dialog as shown here:

25 Services <div>
<button ng-click=”getResponse()”>Close Dialog
</button>
If you need to share state across your application, or need a </div>
solution for data storage or cache, think of Services. Services
are singletons and can be used by other components such as In dialog-controller.js file, use the following code:
directives, controllers, filters and even other services. Services dialog.controller(“diagCtrl”, function ($scope) {
do not have a scope of their own, so it is permissible to add $scope.response = false;
eventlisteners in Services using $rootScope.
$scope.getResponse = function () {

26 Deferred and Promise }


$scope.response = false;

});
The $q service provides deferred objects/promises.
This reduces the coupling between the view and controller
• $q.all([array of promises]) - creates a Deferred object that is
resolved when all of the input promises in the specified array
are resolved in future
28 Prototypal Inheritance

Always have a ‘.’ in your ng-models which insures


• $q.defer() - creates a deferred object with a promise property
prototypal inheritance. So instead of
that can be passed around applications, especially in scenarios
<input type=”text” ng-model=”someprop”>
where we are integrating with a 3rd-party library
use
<input type=”text” ng-model=”someobj.someprop”>

08 www.dotnetcurry.com/magazine
29 Event Aggregator: certain interval. If count is not passed, it defaults to 0, which
causes the call to happen indefinitely.
$scope includes support for event aggregation. It is possible to
publish and subscribe events inside an AngularJS application $interval(function () {
//Logic to execute
without need of a third party library. Following methods are
}, 1000, 10, true);
used for event aggregation:

• $broadcast(eventName, eventObject): Publishes an event


to the current scope and to all children scopes of the current 32 jqLite and jQuery
scope
AngularJS uses a lighter version of jQuery called jqLite to
perform DOM manipulations. The element we receive in
• $emit(eventName, eventObject): Publishes an event to the
compile and link functions of directive are jqLite objects. It
current scope and to all parent scopes of the current scope
provides most of the necessary operations of jQuery. Following
snippet shows obtaining a jqLite object for all divs on a page
• $on(eventName, eventHandler): Listens to an event and
using selector:
executes logic inside eventHandler when the event occurs.

var divJqliteObject = angular.element(‘div’);


30 $resource
But, if jQuery library is referred on the page before referring
$resource is a higher level service that wraps $http to interact AngularJS, then Angular uses jQuery and all element objects are
with RESTful APIs. It returns a class object that can perform created as jQuery objects.
a default set of actions (get (GET), save (POST), query (GET),
remove(DELETE), delete (DELETE)). We can add more actions to If a jQuery plugin library is referred on the page before
the object obtained. referring AngularJS, then the element objects get capabilities of
the extended features that the plugins bring in.
//A factory using $resource
myModule.factory(‘Student’, function($resource){
return $resource(‘/api/students’, null, {
change: {method: ‘PUT’}
33 ngCookie:

}); ngCookie is a module from the AngularJS team that wraps


}); cookies and provides an easier way to deal with cookies in an
The above operation returns a $resource object that has all AngularJS application. It has two services:
default operations and the change method that performs a PUT
operation. i. $cookieStore: Provides a key-value pair kind of interface to
talk to the cookies in the browser. It has methods to get value
31 $timeout and $interval of a stored cookie, set value to a cookie and remove a cookie.
The data is automatically serialized/de-serialized to/from JSON.
$timeout is used to execute a piece of code after certain
interval of time. The $timeout function takes three ii. $cookies: An object representing the cookies. Can be used
parameters: function to execute after time lapse, time to wait directly to get or set values to cookies
in milliseconds, a flag field indicating whether to perform
$scope.$apply after the function execution.
34 Unit testing:
$timeout(function () {
//Logic to execute AngularJS is built with unit testing in mind. Every component
}, 1000, true); defined in Angular is testable. Dependency injection is the key
factor behind it. Take any kind of component in Angular, it can’t
$interval is used to keep calling a piece of code repeatedly after be written without getting some of the external components

www.dotnetcurry.com/magazine 09
injected in. This gives freedom to programmers to pass any 37 Testing controllers:
object of their choice instead of the actual component object
while writing tests. The only thing to be taken care is to create In an AngularJS application, we generally don’t need to create
an object with the same shim as the component. an object of a controller manually. It gets created whenever
a view loads or the template containing an ng-controller
AngularJS code can be unit tested using any JavaScript Unit directive loads. To create it manually, we need to use the
Testing framework like QUnit, Jasmine, Mocha or any other $controller service. To test the behavior of controller, we need to
framework. Jasmine is the most widely used testing framework manually create object of the controller.
with Angular. Tests can be run anywhere, in browser or even in
console using Karma test runner. inject(function($controller){
var controller = $controller(‘myController’,
The main difference between application code and unit tests { $scope: scope, service: serviceMock });
});
is, application code is backed by the framework and browser,
whereas unit tests are totally under our control. So, wherever
As we see, arguments to the controller are passed using a
we get objects automatically injected or created by AngularJS,
JavaScript object literal. They would be mapped to right objects
these objects are not available in unit tests. They have to be
according to names of the services. After this, the scope would
created manually.
have all properties and methods that are set in the controller.
We can invoke them to test their behavior.
35 Bootstrapping a unit test:
it(‘should return 10’, function(){
Just like the case of Angular application, we need to bootstrap var val = scope.getValue();
a module in unit tests to load the module. As the module expect(val).toEqual(10);
});
has to be loaded fresh before any test runs, we load module
while setting up the tests. In Jasmine tests, setup is doe using
beforeEach block. 38 Testing services:

beforeEach(function(){
Getting object of a service is easy as it is directly available to
module(‘myModule’);
the inject() method.
});

var serviceObj;
36 Creating $scope in unit tests: beforeEach(inject(function (myService) {
serviceObj = service;
}));
$scope is a special injectable in AngularJS. It is unlike other
objects as it is not already created to pass into a component
Now any public method exposed from the service can be called
when asked. A $scope can be injected only inside controllers
and the result can be tested using assertions.
and for every request of $scope, a new $scope object is created
that is inherited from $rootScope. Framework takes care of
it(‘should get some data’, function(){
creating the scope when the application is executed. We have
var data = serviceObj.getCustomers();
to do it manually to get a $scope object in tests. Following expect(data).not.toBe(null);
snippet demonstrates creation of $scope: expect(data).not.toBe(undefined);
});
var scope;

beforeEach(inject(function ($rootScope) { 39 ng-controller outside ng-view:


scope = $rootScope.$new();
})); Though controllers are used with views in general, it doesn’t
mean that they can’t be used outside a view. A controller can
be made responsible to load menu items, show toast messages,

10 www.dotnetcurry.com/magazine
update user when a background task is completed or any such and ask Angular’s injector to return the object whenever the
thing that doesn’t depend on the view loaded inside ng-view. service is requested.

<div ng-app=”myModule”> var mockCustomersSvc;


<div ng-controller=”menuController”>
<!-- Mark-up displaying Menu --> beforEach(function(){
</div> mockCustomerService = {
<div ng-view></div> getCustomers: jasmine.createSpy(‘getCustomers’),
</div> getCustomer: jasmine.createSpy(‘getCustomer’),
addCustomers: jasmine.createSpy(‘addCustomer’)
};
40
module(function($provide){
To avoid controllers from getting too complicated, you can $provide.value(‘customersSvc’, mockCustomersSvc);
split the behavior by creating Nested Controllers. This lets you });
});
define common functionality in a parent controller and use
it one or more child controllers. The child controller inherits
all properties of the outside scope and in case of equality,
overrides the properties.
42 ngMock

The ngMock module provides useful tools for unit testing


<body ng-controller=”mainCtrller”>
AngularJS components such as controllers, filters, directives and
<div ng-controller=”firstChildCtrller”>
services.
</div>
</body>
• The module function of ngMock loads the module you want
to test and it’s inject method resolves the dependencies on the
41 Mocking services: service to be tested

Mocking is one of the most crucial things in unit testing. It • We can mock the backend and test components depending
helps in keeping the system under test isolated from any on the $http service using the $httpBackend service in ngMocks
dependency that it has. It is very common to have a component
to depend on a service to get a piece of work done. This work • We can mock timeouts and intervals using $interval and
has to be suppressed in unit tests and replaced with a mock or $timeout in ngMocks
stub. Following snippet mocks a service:
• The $log service can be used for test logging
Say, we have following service:
• The $filter service allows us to test filters
app.service(‘customersSvc’, function(){
this.getCustomers = function(){ • Directives are complex to test. Use the $compile service and
//get customers and return
jqLite to test directives
};
this.getCustomer = function(id){

};
//get the customer and return 43 ng-class:

this.addCustomer = function(customer){ ng-class can be used in multiple ways to dynamically apply


//add the customer
one or more CSS classes to an HTML element. One of the very
};
good features is, it supports some simple logical operators too.
});
Following list shows different ways of using ng-class:

To mock this service, we need to create a simple object with


i. <div ng-class=”dynamicClass”>some text</div>
three mocks with the names same as the ones in the service

www.dotnetcurry.com/magazine 11
Assigns value of dynamicClass from scope to the CSS class. It is In the above snippet, the route won’t be resolved if the promise
two-way bound, i.e. if value of dynamicClass changes, the style is rejected. Resolve block can be injected into the controller and
applied on the div also changes. data resolved from the resolve block can be accessed using the
injected object.
ii. <div class=”[class1, class2, class3]”>some text</div>

All classes mentioned in the array are applied


45 $compile

Used to compile templates after the compilation phase.


iii. <div class=”{‘’my-class-1’’:value1, ‘’my-class-
$compile is generally used in link function of directives
2’’:value2}”>some text</div>
or services. But, it should be used with caution as manual
compilation is an expensive operation.
my-class-1 is applied when value1 is assigned with a truthy
value (other than false, empty string, undefined or null)
myModule.directive(‘sampleDirective’, function(){
return {
iv. <div ng-class=”value ? ‘my-class-1’:’my-class- link: function(scope, elem, attrs){
2’”>some text</div> var compiled = $compile(‘<div>{{person.name}}
</div>’)(scope);
Value of class applied is based on result of the ternary operator. elem.html(compiled);
}
};
v. <div ng-class=”{true: ‘firstclass’}[applyfirstclass] ||
});
{true:’secondclass’}[applysecondclass]”></div>

Here, applyFirstClass and applySecondClass are data bound 46 $parse


variables. The expression applies firstClass if applyFirstClass is
true. It applies secondClass only if applySecondClass is true and $parse is used to transform plain text into expression. The
applyFirstClass is false. expression can be evaluated against any object context to
obtain the value corresponding to the object. Very common
usage of parse is inside directives to parse the text received
44 Resolve blocks in routing: from an attribute and evaluate it against scope. The expression
also can be used to add a watcher.
Resolve blocks are used to load data before a route is resolved.
They can be used to validate authenticity of the user, load myModule.directive(‘sampleDirective’, function($parse){
initial data to be rendered on the view or to establish a real- return function(scope, elem, attrs){
time connection (e.g. Web socket connection) as it would be in var expression = $parse(attrs.tempValue);

use by the view. View is rendered only if all the resolve blocks
var value = expression(scope);
of the view are resolved. Otherwise, the route is cancelled and
scope.$watch(expression, function(newVal, oldVal){
the user is navigated to the previous view. //Logic to be performed
});
$routeProvider.when(‘/details’, { };
templateUrl: ‘detailsView.html’, });
controller: ‘detailsController’,
resolve: {
loadData: function (dataSvc, $q) { 47 Route change events:
var deferred = $q.defer;
dataSvc.getDetails(10).then( When a user navigates from one page to another, AngularJS
function (data) { deferred.reslve(data);},
broadcasts events at different phases. One can listen to these
function () { deferred.reject();});
events and take appropriate action like verifying login status,
return deferred.promise;
requesting for data needed for the page or even to count the
}
}}); number of hits on a view. Following are the events raised:

12 www.dotnetcurry.com/magazine
• $routeChangeStart 50 HTTP Interceptors
• $routeChangeSuccess
• $routeChangeError Any HTTP request sent through $http service can be
• $routeUpdate intercepted to perform certain operation at a given state. The
state may be one of the following: before sending request, on

48 Decorating request error, after receiving response and on response error.


Interceptors are generally used to check authenticity of the
It is possible to modify the behavior or extend the functionality request before sending to the server or to displaying some kind
of any object in AngularJS through decoration. Decoration is of wait indicator to the user when the user has to wait for the
applied in AngularJS using $provide provider. It has to be done data to arrive. The intercepting methods may return either plain
in config block. Following example adds a method to the value: data or a promise.

angular.module(‘myModule’,[]) myModule.config(function ($provide) {


.config(function($provide) { $provide.factory(‘myHttpInterceptor’, function () {
$provide.decorator(‘someValue’, function($delegate) return {
{ request: function (req) {
$delegate.secondFn = function(){ //logic before sending request
console.log(“Second Function”); },
}; response: function (res) {
//logic after receiving response
return $delegate; },
}); requestError: function () {
}) //logic on request error
.value(‘someValue’,{ },
firstFn: function(){console.log(“First Function”);} responseError: function () {
}); //logic on response error
}
};
Note: Constants cannot be decorated });
});

49 Exception handling
51 HTTP Transforms
All unhandled exceptions in an AngularJS application are
Transforms allow us to tweak the data before sending to
passed to a service $exceptionHandler, which logs the
an HTTP request or after receiving response at the end of a
error message in the browser’s console. In large business
request. It can be applied either globally using a config block or
applications, you may want to log the error details on the
on a specific request using the $http config object.
server by calling an API. This can be done by decorating the
$exceptionHandler service.
Setting transform in config block:
myApp.config(function ($provide) {
$provide.decorator(‘$exceptionHandler’, [‘$log’, myModule.config(function ($httpProvider) {
‘$http’, ‘$delegate’, $httpProvider.defaults.transformRequest.push(function
function ($log, $http, $delegate) { (data) { //Operate on data });
return function (exception, cause) { });
$log.debug(‘Modified exception handler’);
$http.post(‘/api/clientExceptionLogger’, In the individual request:
exception);
$delegate(exception, cause); $http({
}; url: ‘/api/values’,
} method: ‘GET’,
]); transformRequest: function (data) {//Operate on data}
}); });

www.dotnetcurry.com/magazine 13
Some useful AngularJS Tools & Libraries Ravi Kiran is a developer working on
Microsoft Technologies. These days,
• Visual Studio Express (free), Sublime (paid), NetBeans (free) or he spends his time on the front-end
WebStorm (paid) for AngularJS Development JavaScript framework Angular JS and
• Batarang Chrome Development Plugin (bit.ly/dncm15- server frameworks like ASP.NET Web
batarang) for debugging and profiling AngularJS applications API and SignalR. He actively writes
• AngularUI (angular-ui.github.io/ ) and ngModules what he learns on his blog at sravi-
(ngmodules.org ) are a good place to look out for commonly kiran.blogspot.com. He is a DZone
used modules MVB. You can follow him on twitter at @sravi_kiran
• Angular Seed (bit.ly/dncm15-angularseed ), ngBoilerplate
(github.com/ngbp/ngbp) and Yeoman (yeoman.io/) can be used
for workflow and project structure management Suprotim Agarwal, ASP.NET Architecture MVP
• The Iconic Framework (http://ionicframework.com) is an is an author and the founder of
Angular wrapper around PhoneGap; can be used to build hybrid popular .NET websites like dotnetcurry.com,
mobile apps with Angular devcurry.com and the DNC .NET Magazine.
You can follow him on twitter
@suprotimagarwal or check out his new
Some useful companion libraries in book www.jquerycookbook.com
AngularJS

• AngularUI-Bootstrap (github.com/angular-ui/bootstrap)
provides native AngularJS directives for Bootstrap (No need of
jQuery)
• AngularUI-Utils (github.com/angular-ui/ui-utils) contains a
bunch of essential utilities (included with ng-boilerplate)
• AngularUI (angular-ui.github.io/) ports off many jQueryUI
components to Angular
• Angular translate (angular-translate.github.io) makes it easier
to apply internationalization to Angular projects
• Restangular (github.com/mgonto/restangular) A clean,
promise-based, feature rich 3rd-party library that provides some
useful abstractions, especially for complex operations on the
client-side.
• AngularFire (firebase.com/docs/web/libraries/angular/): An
abstraction to interact with Firebase realtime database
• Breeze.js (breezejs.com): A library for rich data operations in
AngularJS apps. Also contains directives for data validations
Main.ts:
import { platformBrowserDynamic } from
'@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

Index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tour of Heroes</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

Mock-heroes.ts:
import { Hero } from './hero';

export const HEROES: Hero[] = [


{ id: 12, name: 'Dr. Nice' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr. IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];

Message.service.ts:
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })


export class MessageService {
messages: string[] = [];

add(message: string) {
this.messages.push(message);
}

clear() {
this.messages = [];
}
}

In-memory-data.services.ts
import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Hero } from './hero';

@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const heroes = [
{ id: 12, name: 'Dr. Nice' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr. IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
return {heroes};
}

// Overrides the genId method to ensure that a hero always has an id.
// If the heroes array is empty,
// the method below returns the initial number (11).
// if the heroes array is not empty, the method below returns the
highest
// hero id + 1.
genId(heroes: Hero[]): number {
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id))
+ 1 : 11;
}
}

Hero.ts:
export interface Hero {
id: number;
name: string;
}

Hero.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable, of } from 'rxjs';


import { catchError, map, tap } from 'rxjs/operators';

import { Hero } from './hero';


import { MessageService } from './message.service';

@Injectable({ providedIn: 'root' })


export class HeroService {

private heroesUrl = 'api/heroes'; // URL to web api

httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

constructor(
private http: HttpClient,
private messageService: MessageService) { }

/** GET heroes from the server */


getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(_ => this.log('fetched heroes')),
catchError(this.handleError<Hero[]>('getHeroes', []))
);
}
/** GET hero by id. Return `undefined` when id not found */
getHeroNo404<Data>(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/?id=${id}`;
return this.http.get<Hero[]>(url)
.pipe(
map(heroes => heroes[0]), // returns a {0|1} element array
tap(h => {
const outcome = h ? 'fetched' : 'did not find';
this.log(`${outcome} hero id=${id}`);
}),
catchError(this.handleError<Hero>(`getHero id=${id}`))
);
}

/** GET hero by id. Will 404 if id not found */


getHero(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/${id}`;
return this.http.get<Hero>(url).pipe(
tap(_ => this.log(`fetched hero id=${id}`)),
catchError(this.handleError<Hero>(`getHero id=${id}`))
);
}

/* GET heroes whose name contains search term */


searchHeroes(term: string): Observable<Hero[]> {
if (!term.trim()) {
// if not search term, return empty hero array.
return of([]);
}
return
this.http.get<Hero[]>(`${this.heroesUrl}/?name=${term}`).pipe(
tap(x => x.length ?
this.log(`found heroes matching "${term}"`) :
this.log(`no heroes matching "${term}"`)),
catchError(this.handleError<Hero[]>('searchHeroes', []))
);
}

//////// Save methods //////////

/** POST: add a new hero to the server */


addHero(hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero,
this.httpOptions).pipe(
tap((newHero: Hero) => this.log(`added hero w/
id=${newHero.id}`)),
catchError(this.handleError<Hero>('addHero'))
);
}

/** DELETE: delete the hero from the server */


deleteHero(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/${id}`;

return this.http.delete<Hero>(url, this.httpOptions).pipe(


tap(_ => this.log(`deleted hero id=${id}`)),
catchError(this.handleError<Hero>('deleteHero'))
);
}

/** PUT: update the hero on the server */


updateHero(hero: Hero): Observable<any> {
return this.http.put(this.heroesUrl, hero, this.httpOptions).pipe(
tap(_ => this.log(`updated hero id=${hero.id}`)),
catchError(this.handleError<any>('updateHero'))
);
}

/**
* Handle Http operation that failed.
* Let the app continue.
*
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {

// TODO: send the error to remote logging infrastructure


console.error(error); // log to console instead

// TODO: better job of transforming error for user consumption


this.log(`${operation} failed: ${error.message}`);

// Let the app keep running by returning an empty result.


return of(result as T);
};
}

/** Log a HeroService message with the MessageService */


private log(message: string) {
this.messageService.add(`HeroService: ${message}`);
}
}

App.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { HttpClientInMemoryWebApiModule } from


'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';

import { AppRoutingModule } from './app-routing.module';

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


import { DashboardComponent } from './dashboard/dashboard.component';
import { HeroDetailComponent } from
'./hero-detail/hero-detail.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroSearchComponent } from
'./hero-search/hero-search.component';
import { MessagesComponent } from './messages/messages.component';

@NgModule({
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
HttpClientModule,

// The HttpClientInMemoryWebApiModule module intercepts HTTP


requests
// and returns simulated server responses.
// Remove it when a real server is ready to receive requests.
HttpClientInMemoryWebApiModule.forRoot(
InMemoryDataService, { dataEncapsulation: false }
)
],
declarations: [
AppComponent,
DashboardComponent,
HeroesComponent,
HeroDetailComponent,
MessagesComponent,
HeroSearchComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }

App.component.ts:
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
}

App.component.html:
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
<app-messages></app-messages>

App.component.css:
Css here

App-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { DashboardComponent } from './dashboard/dashboard.component';


import { HeroesComponent } from './heroes/heroes.component';
import { HeroDetailComponent } from
'./hero-detail/hero-detail.component';

const routes: Routes = [


{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];

@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}

Components created using cli


Heroes component:

Heroes.component.ts:
import { Component, OnInit } from '@angular/core';

import { Hero } from '../hero';


import { HeroService } from '../hero.service';

@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
heroes: Hero[] = [];

constructor(private heroService: HeroService) { }

ngOnInit(): void {
this.getHeroes();
}

getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}

add(name: string): void {


name = name.trim();
if (!name) { return; }
this.heroService.addHero({ name } as Hero)
.subscribe(hero => {
this.heroes.push(hero);
});
}

delete(hero: Hero): void {


this.heroes = this.heroes.filter(h => h !== hero);
this.heroService.deleteHero(hero.id).subscribe();
}

Heroes.component.html:
<h2>My Heroes</h2>

<div>
<label for="new-hero">Hero name: </label>
<input id="new-hero" #heroName />

<!-- (click) passes input value to add() and then clears the input
-->
<button type="button" class="add-button"
(click)="add(heroName.value); heroName.value=''">
Add hero
</button>
</div>

<ul class="heroes">
<li *ngFor="let hero of heroes">
<a routerLink="/detail/{{hero.id}}">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</a>
<button type="button" class="delete" title="delete hero"
(click)="delete(hero)">x</button>
</li>
</ul>
Heroes.component.css:
Css

Hero-search component:

Hero-search.component.ts:
import { Component, OnInit } from '@angular/core';

import { Observable, Subject } from 'rxjs';

import {
debounceTime, distinctUntilChanged, switchMap
} from 'rxjs/operators';

import { Hero } from '../hero';


import { HeroService } from '../hero.service';

@Component({
selector: 'app-hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ]
})
export class HeroSearchComponent implements OnInit {
heroes$!: Observable<Hero[]>;
private searchTerms = new Subject<string>();

constructor(private heroService: HeroService) {}

// Push a search term into the observable stream.


search(term: string): void {
this.searchTerms.next(term);
}

ngOnInit(): void {
this.heroes$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),

// ignore new term if same as previous term


distinctUntilChanged(),

// switch to new search observable each time the term changes


switchMap((term: string) => this.heroService.searchHeroes(term)),
);
}
}

Hero-search.component.html:
<div id="search-component">
<label for="search-box">Hero Search</label>
<input #searchBox id="search-box" (input)="search(searchBox.value)"
/>

<ul class="search-result">
<li *ngFor="let hero of heroes$ | async" >
<a routerLink="/detail/{{hero.id}}">
{{hero.name}}
</a>
</li>
</ul>
</div>

Hero-search.component.css:
Css

Hero-detail component:

Hero-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';

import { Hero } from '../hero';


import { HeroService } from '../hero.service';

@Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: [ './hero-detail.component.css' ]
})
export class HeroDetailComponent implements OnInit {
hero: Hero | undefined;

constructor(
private route: ActivatedRoute,
private heroService: HeroService,
private location: Location
) {}

ngOnInit(): void {
this.getHero();
}

getHero(): void {
const id = parseInt(this.route.snapshot.paramMap.get('id')!, 10);
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
}

goBack(): void {
this.location.back();
}

save(): void {
if (this.hero) {
this.heroService.updateHero(this.hero)
.subscribe(() => this.goBack());
}
}
}

Hero-detail.component.html:
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label for="hero-name">Hero name: </label>
<input id="hero-name" [(ngModel)]="hero.name" placeholder="Hero
name"/>
</div>
<button type="button" (click)="goBack()">go back</button>
<button type="button" (click)="save()">save</button>
</div>

Hero-detail.component.css:
Css
Dashboard component

Dashboard.component.ts:
import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';

@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.css' ]
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];

constructor(private heroService: HeroService) { }

ngOnInit(): void {
this.getHeroes();
}

getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes.slice(1, 5));
}
}

Dashboard.component.html:
<h2>Top Heroes</h2>
<div class="heroes-menu">
<a *ngFor="let hero of heroes"
routerLink="/detail/{{hero.id}}">
{{hero.name}}
</a>
</div>

<app-hero-search></app-hero-search>

Dashboard.component.css:
Css
Message component:

Message.component.ts:
import { Component } from '@angular/core';
import { MessageService } from '../message.service';

@Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent {

constructor(public messageService: MessageService) {}

Message.component.html:
<div *ngIf="messageService.messages.length">

<h2>Messages</h2>
<button type="button"
class="clear"
(click)="messageService.clear()">Clear messages</button>
<div *ngFor='let message of messageService.messages'> {{message}}
</div>

</div>
AngularJS Cheat Sheet
by ProLoser via cheatography.com/1600/cs/513/

Filters Services Services (cont)

amount | currency[:symbol] $anc​hor​Scr​oll $win​dow


Formats a number as a currency (ie $cac​heF​act​ory
$1,234.56). Directive Definition Object
compil​edHtml = $com​pil​e ​(ht​ml)​(scope)
date | date[:format] name {string}
$con​tro​ller
array | filter:expression Name of the current scope. Optional
$coo​kie​Store
defaults to the name at regist​ration.
Selects a subset of items from array. $doc​ument
Expression takes strin​g|O​bje​ct|​fun​cti​on() prio​rity {inte​ger}
$exc​ept​ion​Han​dle​r​(ex​cep​tion[, cause])
data | json Specifies order multiple directives apply
$fil​ter​(​name)
on single DOM element (higher = first)
Convert a JavaScript object into JSON $htt​p​[(​opt​ions)]
string. term​inal {true}
$htt​pBa​ckend
array | limitTo:limit Current priority will be last set of
$inj​ector
directives to execute
Creates a new array containing only a
$int​erp​ola​te​(t​ext[, mustHa​veE​xpr​ess​ion])
specified number of elements in an scope {true | object}
$loc​ale
array. True - create child scope. Undef​ine​d|f​‐
$loc​ation
text | linky 1 alse - use parent scope. {} - isolate
$log scope (with specified attrib​ute​s/scope
Finds links in text input and turns them
$par​se​(e​xpr​ession) variables passed): @ or @attr - bind
into html links.
local model to value of DOM attribute
$pro​vide
string | lowercase (string), = or =attr - bi-dir​ect​ional binding
$q
Converts string to lowercase. between local model and the parent
$res​our​ce​(url[, paramD​efa​ults][, actions]) scope, & or &attr - execute an
number | number[:fractionSize]
$roo​tEl​ement expression in context of parent.
Formats a number as text. If the input is
$roo​tSc​ope Reference attr OR assumes model of
not a number an empty string is returned.
same name
$route
array | orderBy:predicate[:reverse]
cont​rol​ler funct​ion​($s​cope, $element,
$rou​teP​arams
Predicate is functi​on(​*)|​str​ing​|Array. $attrs, $trans​clude)
Reverse is boolean $rou​teP​rov​ider
Controller constr​uctor function instan​‐
$san​iti​ze​(html)
string | uppercase tiated before pre-li​nking phase and
$scope See $rootS​cope shared with other directives if requested
Converts string to uppercase.
$tem​pla​teC​ache by name
You can inject the $filter service and do
$tim​eou​t ​(fn[, delay][, invoke​App​ly])
$filt​er(​'fi​lte​rNa​me'​)(v​alue[, :optio​nal​Par​am][,
:optio​nal​Par​am]) in use it in your javasc​ript.
1 Requires ngSanitize Module

By ProLoser Published 9th August, 2012. Sponsored by CrosswordCheats.com


cheatography.com/proloser/ Last updated 29th February, 2020. Learn to solve cryptic crosswords!
Page 1 of 5. http://crosswordcheats.com
AngularJS Cheat Sheet
by ProLoser via cheatography.com/1600/cs/513/

Directive Definition Object (cont) Directives Directives (cont)

requ​ire {string | array[​str​ings]} ng-app="plaintext" ng-readonly="expression"


Require another controller (ngMo​‐ ng-bind[-html-unsafe]="expression" ng-repeat="([key,] value) in object|array"
del). Prefixes: ? - Don't raise error. ^ ng-bind- <option ng-selected="boolean">
- Look on parent elements too template="string{{expression}}string{{expression}}" ng-src="string"
rest​rict {string: 'EACM'} ng-change="expression" ng-style="string|object"
E - Element: <m​y-d​ire​ctive />. A - ng-checked="boolean" ng-submit="expression"
Attrib​ute (default): <div my-di​rec​tiv​‐
ng-class[-even|-odd]="string|object" ng-switch="expression"|<ng-switch
e=​"​exp​" />. C - Class: <div
ng-[dbl]click="expression" on="expression">
class=​"m
​ y​-di​rec​tive: exp;" />. M -
Comment: <!-- directive: my-di​rec​‐ ng-cloak="boolean" ng-s​wit​ch-​whe​n​="pl​ain​tex​t"
tive exp --> ng-controller="plaintext" ng-s​wit​ch-​def​ault

temp​late {string} <html ng-csp> (Content Security Policy) ng-transclude templates

Replace current element with ng-disabled="boolean" ng-view|<ng-view>


contents and migrates all attributes / <form|ng-form name="plaintext"> | ng- ng-bind-html="expression"
classes form="plaintext"
Bold means the actual directive
temp​lat​eUrl {string} ng-hide|show="boolean" Italics mean optional
Same as template but the template is ng-href="plaintext{{string}}" Pipes mean either|or
loaded from the specified URL Plaintext means no string encaps​ulation
ng-include="string"|<ng-include src="string"
Super​script means notes or context
repl​ace {bool​ean} onload="expression" autoscroll="expression">
<Br​ack​ets> mean tag compti​bility
true: template replaces element ng-init="expression"
Lack of <br​ack​ets> means the attribute
instead of appending <input ng-p​att​ern​=​"​/re​gex​/" ng-m​inl​ength ng-m​‐ can apply to any tag
tran​scl​ude {bool​ean} axl​ength ng-r​equ​ired

Compiles contents on parent (pre-i​‐ <input ng-list="delimiter|regex"> Module


solate) scope. Usually used with <input type="c​hec​kbo​x" ng-t​rue​-va​lue​ =​"​pla​int​‐ config(configFn)
ngTran​sclude & templates. ext​" ng-f​als​e-v​alu​e​="pl​ain​tex​t">
Use this method to register work
comp​ile funct​ion​(tE​lement, tAttrs, fn ng-model="expression" which needs to be performed on
transc​lud​e(f​unc​tio​n(s​cope, cloneL​ink​‐ ng-mousedown="expression" module loading.
ingFn) ) returns link()
ng-mouseenter="expression" constant(name, object)
For transf​orming the template (rare,
ng-mouseleave="expression" Because the constant are fixed, they
run once per template instance).
ng-mousemove="expression" get applied before other provide
link funct​ion​(scope, iElement, iAttrs, methods.
ng-mouseover="expression"
contro​ller)
ng-mouseup="expression" controller(name, constructor)
Executed after template is cloned
<select ng-m​ult​ipl​e> directive(name, directiveFactory)
(run once per clone). Contains most
ng-non-bindable factory(name, providerFunction)
logic (DOM listeners, etc). Contr​oller
can be an array. ng-options="select [as label] [group by group] for filter(name, filterFactory)

([key,] value) in object|array" provider(name, providerType)


http:/​/do​cs.a​ng​ula​rjs.or​g/g​uid​e/d​ire​ctive
ng-pluralize|<ng-pluralize count="number"
when="object" offset="number">

By ProLoser Published 9th August, 2012. Sponsored by CrosswordCheats.com


cheatography.com/proloser/ Last updated 29th February, 2020. Learn to solve cryptic crosswords!
Page 2 of 5. http://crosswordcheats.com
AngularJS Cheat Sheet
by ProLoser via cheatography.com/1600/cs/513/

Module (cont) Scope Properties and Methods (cont) Global Functions

run(initializationFn) $des​tro​y() angular.bind(self, fn, args)


Use this method to register work which Removes the current scope (and all of its Returns a function which calls function fn
needs to be performed when the injector children) from the parent scope bound to self (self becomes the this for
with with the current module is finished fn).
$dig​est()
loading.
Process all of the watchers of the current angular.bootstrap(element[, modules])
service(name, constructor) scope and its children. Since watchers Use this function to manually start up
value(​name, object) can change models, they will continue angular applic​ation.
firing until all changes stop. BEWARE
name angular.copy(source[, destination])
OF RECURSIVE CODE
Name of the module. Creates a deep copy of source, which
$emi​t(name, args) should be an object or an array.
Holds the list of modules which the
Dispatches an event name upwards
injector will load before the current angular.element(element)
through the scope hierarchy
module is loaded. Wraps a raw DOM element or HTML
$eva​l(e​xpr​ess​ion) string as a jQuery element.
http:/​/do​cs.a​ng​ula​rjs.or​g/a​pi/​ang​ula​r.M​odule
Executes the expression on the current
angular.equals(o1, o2)
scope and returns the result
Scope Properties and Methods Determines if two objects or two values
$eva​lAs​ync​(ex​pre​ssi​on) are equiva​lent.
$root or $roo​tSc​ope
Executes the expression on the current
Move to the top-most $scope (ng-app) angular.extend(dst, src)
scope at a later point in time
$par​ent Extends the destin​ation object dst by
$new​(is​ola​te) copying all of the properties from the src
Move to the immediate parent of the
Creates a new child scope object(s) to dst.
current $scope
$on(​name, listen​er) angular.forEach(obj, iterator[, context])
$id
Listens on events of a given type Invokes the iterator function once for
Auto generated Unique ID
each item in obj collec​tion, which can be
$wat​ch(​wat​chExp, listen​er(​newVal,
$destroy (event) either an object or an array.
oldVal, scope), object​Equ​ali​ty)
Broadc​asted when a scope and its
Watch a model (exp) for changes and angular.fromJson(json)
children are being destroyed
fires the listener callback. Pass true as a Deseri​alizes a JSON string.
$app​ly(​exp) third argument to watch an object's
Executes logic within the AngularJS properties too.
context and refreshes all models checks.
The following directives create child
$bro​adc​ast​(name, args) scopes: ngInc​lude, ngSwi​tch, ngRep​eat,
Dispatches an event name downwards ngCon​tro​ller, uiIf. Calls to the same ngCon​‐
to all child scopes tro​ller will create multiple instances and do
not share scopes. Remember to traverse
up the tree to affect primi​tives on the
intended scope: ng-cl​ick​="$p​are​nt.s​ho​wPa​‐
ge=​tru​e"

By ProLoser Published 9th August, 2012. Sponsored by CrosswordCheats.com


cheatography.com/proloser/ Last updated 29th February, 2020. Learn to solve cryptic crosswords!
Page 3 of 5. http://crosswordcheats.com
AngularJS Cheat Sheet
by ProLoser via cheatography.com/1600/cs/513/

Global Functions (cont) Global Functions (cont) NgMode​lCo​ntr​oller

angular.identity() angular.lowercase(string) $render() Called when the view needs


A function that returns its first argument. Converts the specified string to to be updated. It is expected
This function is useful when writing code lowercase. that the user of the ng-model
in the functional style. directive will implement this
angular.mock
method.
angular.injector(modules) Namespace from 'angul​ar-​moc​ks.js'
$setVa​lid​ity​(va​lid​ati​onE​rro​rKey, isValid)
Creates an injector function that can be which contains testing related code.
$setVi​ewV​alu​e(v​alue)
used for retrieving services as well as for
angular.module(name[, requires],
dependency injection. $viewValue mixed
configFn)
angular.isArray(value) $model​‐ mixed
The angula​r.m​odule is a global place for
Value
Determines if a reference is an Array. creating and regist​ering Angular
modules. Requires argument always $parsers array of function after reading
angular.isDate(value)
creates a new module. val from DOM to sanitize /
Determines if a value is a date. convert / validate the value
angular.noop()
angular.isDefined(value) $forma​tters array of functions to convert /
A function that performs no operat​ions.
Determines if a reference is defined. validate the value
angular.toJson(obj[, pretty])
angular.isElement(value) $error object
Serializes input into a JSON-f​orm​atted
Determines if a reference is a DOM $pristine boolean
string.
element (or wrapped jQuery element). $dirty boolean
angular.uppercase(string)
angular.isFunction(value) $valid boolean
Converts the specified string to
Determines if a reference is a Function. $invalid boolean
uppercase.
angular.isNumber(value) http:/​/do​cs.a​ng​ula​rjs.or​g/a​pi/​ng.d​ir​ect​ive​:ng​‐
angular.version
Mod​el.N​gM​ode​lCo​ntr​oller
Determines if a reference is a Number.
An object that contains inform​ation about
angular.isObject(value) the current AngularJS version.
Determines if a reference is an Object.
Unlike typeof in JavaSc​ript, nulls are not FormCo​ntr​oller
considered to be objects.
$pristine
angular.isString(value) $dirty
Determines if a reference is a String. $valid
angular.isUndefined(value) $invalid
Determines if a reference is undefined. $error

http:/​/do​cs.a​ng​ula​rjs.or​g/a​pi/​ng.d​ir​ect​ive​:fo​‐
rm.F​or​mCo​ntr​oller

By ProLoser Published 9th August, 2012. Sponsored by CrosswordCheats.com


cheatography.com/proloser/ Last updated 29th February, 2020. Learn to solve cryptic crosswords!
Page 4 of 5. http://crosswordcheats.com
AngularJS Cheat Sheet
by ProLoser via cheatography.com/1600/cs/513/

Deferred and Promise

$q.a​ll(​[array of promis​es])
Creates a Deferred object which represents a task which will finish
in the future.

$q. defer()
Creates a Deferred object which represents a task which will finish
in the future.

$q.r​eje​ct(​re​aso​n)
Creates a promise that is resolved as rejected with the specified
reason

$q.w​hen​( v​alu​e)
Wraps an object that might be a value or a (3rd party) then-able
promise into a $q promise

Defe​rre​d.r​eso​lve​( v​alu​e)
Resolves the derived promise with the value

Defe​rre​d.r​eje​ct(​re​aso​n)
Rejects the derived promise with the reason

Defe​rre​d.p​rom​ise
Promise object associated with this deferred

Prom​ise.th​en(​suc​ces​sCa​llback, errorC​all​back)

http:/​/do​cs.a​ng​ula​rjs.or​g/a​pi/​ng.$q

By ProLoser Published 9th August, 2012. Sponsored by CrosswordCheats.com


cheatography.com/proloser/ Last updated 29th February, 2020. Learn to solve cryptic crosswords!
Page 5 of 5. http://crosswordcheats.com
BOOTSTRAPPING DETAILS

import {
Import platformBrowserDynamic
platformBrowserDynamic }
from
from
@angular/platform-browser-dyn
'@angular/platform-browser
amic.
-dynamic';

Bootstraps the application, using


platformBrowserDynamic().b
the root component from the
ootstrapModule(AppModule);
specified NgModule.

NGMODULES DETAILS

import {
NgModule } from Import NgModule from @angular/core.
'@angular/core';
@NgModule({
declarations: …,
imports: …,
exports: …,
providers: …,
bootstrap: …
}) Defines a module that contains components,
directives, pipes, and providers.

class MyModule
{}

declarations: [
MyRedComponent,
MyBlueComponent,
MyDatePipe
List of components, directives, and pipes that
belong to this module.

]
imports: [
BrowserModule,
SomeOtherModule
List of modules to import into this module.
Everything from the imported modules is
available to declarations of this module.
]

exports: [
MyRedComponent,
MyDatePipe

List of components, directives, and pipes


visible to modules that import this module.
]

providers: [
MyService,
{ provide: … }
List of dependency injection providers visible
both to the contents of this module and to
importers of this module.
]
bootstrap: List of components to bootstrap when this
[MyAppComponent] module is bootstrapped.

TEMPLATE SYNTAX DETAILS

<input Binds property value to the result of


[value]="firstName"> expression firstName.

<div Binds attribute role to the result of


[attr.role]="myAriaRole"> expression myAriaRole.

Binds the presence of the CSS class


<div
extra-sparkle on the element to
[class.extra-sparkle]="isD
the truthiness of the expression
elightful">
isDelightful.
Binds style property width to the
<div
result of expression mySize in
[style.width.px]="mySize">
pixels. Units are optional.

Calls method readRainbow when a


<button
click event is triggered on this button
(click)="readRainbow($even
element (or its children) and passes
t)">
in the event object.

Binds a property to an interpolated


string, for example, "Hello
Seabiscuit". Equivalent to:

<div title="Hello
{{ponyName}}">
<div [title]="'Hello ' +
ponyName">
<p>
Hello {{ponyName}}

Binds text content to an interpolated


string, for example, "Hello
</p> Seabiscuit".

Sets up two-way data binding.


Equivalent to:

<my-cmp [(title)]="name">
<my-cmp [title]="name"
(titleChange)="name=$eve
nt">

<video #movieplayer …></video>


<button
(click)="movieplayer.play()">
Creates a local variable
Play
movieplayer that provides access
to the video element instance in
data-binding and event-binding
</button> expressions in the current template.
The asterisk (*) character turns the
current element into an embedded
template. Equivalent to:
<p *myUnless="myExpression">
… <ng-template
[myUnless]="myExpression">
<p>

</p>
</p>

</ng-template>

<p>
Card No.: {{cardNumber |
myCardNumberFormatter}}
Transforms the current value of
expression cardNumber using the
pipe called
</p> myCardNumberFormatter.
<p>
Employer:
{{employer?.companyName}}
The safe navigation operator (?)
means that the employer field is
optional and if undefined, the rest
</p> of the expression should be ignored.

<svg:rect x="0"
y="0"
width="100"
An SVG snippet template needs an
svg: prefix on its root element to
disambiguate the SVG element from
height="100"/> an HTML component.

<svg>
<rect x="0"
y="0"
width="100"
height="100"/> An <svg> root element is detected
as an SVG element automatically,
without the prefix.

</svg>
BUILT-IN DIRECTIVES DETAILS

import { CommonModule } Import CommonModule from


from '@angular/common'; @angular/common.

Removes or recreates a portion of the


<section
DOM tree based on the showSection
*ngIf="showSection">
expression.

Turns the li element and its contents


<li *ngFor="let item of
into a template, and uses that to
list">
instantiate a view for each item in list.
<div
[ngSwitch]="conditionExpressio
n">
<ng-template
[ngSwitchCase]="case1Exp">

</ng-template>
<ng-template
ngSwitchCase="case2LiteralStri
Conditionally swaps the contents of
ng">
the div by selecting one of the

embedded templates based on the
</ng-template>
current value of
<ng-template
conditionExpression.
ngSwitchDefault>

</ng-template>

</div>

<div [ngClass]="{'active':
isActive,

Binds the presence of CSS classes on


the element to the truthiness of the
associated map values. The
'disabled': right-hand expression should return
isDisabled}"> {class-name: true/false} map.
<div [ngStyle]="{'property':
'value'}">

Allows you to assign styles to an


HTML element using CSS. You can
<div use CSS directly, as in the first
[ngStyle]="dynamicStyles example, or you can call a method
()"> from the component.

FORMS DETAILS

import { FormsModule
Import FormsModule from
} from
@angular/forms.
'@angular/forms';

<input
Provides two-way data-binding, parsing,
[(ngModel)]="userNam
and validation for form controls.
e">

CLASS DECORATORS DETAILS


import {
Directive, … } Import Directive, &hellip; from
from @angular/core';.
'@angular/core';

@Component({…})

Declares that a class is a component and


class
provides metadata about the component.
MyComponent() {}

@Directive({…})

Declares that a class is a directive and


class
provides metadata about the directive.
MyDirective() {}

@Pipe({…})

Declares that a class is a pipe and provides


class MyPipe() {} metadata about the pipe.
@Injectable()

Declares that a class can be provided and


injected by other classes. Without this
class MyService() decorator, the compiler won't generate enough
{} metadata to allow the class to be created
properly when it's injected somewhere.

DIRECTIVE DETAILS
CONFIGURATION

@Directive({
property1: value1,

Add property1 property with value1 value to


Directive.
})
Specifies a CSS selector that identifies this
directive within a template. Supported selectors
selector: include element, [attribute], .class, and
'.cool-button: :not().
not(a)'
Does not support parent-child relationship
selectors.

providers: [
MyService,
{ provide: … }

List of dependency injection providers for this


directive and its children.
]

COMPONENT CONFIGURATION DETAILS

EXTENDS @DIRECTIVE, SO THE @DIRECTIVE


@COMPONENT

CONFIGURATION APPLIES TO COMPONENTS


AS WELL
List of dependency
viewProviders: [MyService, { injection providers
provide: … }] scoped to this
component's view.

template: 'Hello {{name}}'

Inline template or
external template URL of
templateUrl: 'my-component.html'
the component's view.

styles: ['.primary {color: red}']

List of inline CSS styles


or external stylesheet
styleUrls: ['my-component.css'] URLs for styling the
component's view.

CLASS FIELD DECORATORS FOR DETAILS


DIRECTIVES AND COMPONENTS
import { Input, … } from Import Input, ... from
'@angular/core'; @angular/core.

Declares an input property that you


can update using property binding
@Input() myProperty; (example: <my-cmp
[myProperty]="someExpression"
>).

Declares an output property that


fires events that you can subscribe
@Output() myEvent = new
to with an event binding (example:
EventEmitter();
<my-cmp
(myEvent)="doSomething()">).

Binds a host element property


@HostBinding('class.valid' (here, the CSS class valid) to a
) isValid; directive/component property
(isValid).
Subscribes to a host element event
@HostListener('click', (click) with a directive/component
['$event']) onClick(e) {…} method (onClick), optionally
passing an argument ($event).

Binds the first result of the


@ContentChild(myPredicate) component content query
myChildComponent; (myPredicate) to a property
(myChildComponent) of the class.

Binds the results of the component


@ContentChildren(myPredica content query (myPredicate) to a
te) myChildComponents; property (myChildComponents) of
the class.
Binds the first result of the
component view query
@ViewChild(myPredicate)
(myPredicate) to a property
myChildComponent;
(myChildComponent) of the class.
Not available for directives.

Binds the results of the component


view query (myPredicate) to a
@ViewChildren(myPredicate)
property (myChildComponents) of
myChildComponents;
the class. Not available for
directives.

DIRECTIVE AND COMPONENT DETAILS


CHANGE DETECTION AND
LIFECYCLE HOOKS (IMPLEMENTED
AS CLASS METHODS)
Called before any other lifecycle
constructor(myService:
hook. Use it to inject dependencies,
MyService, …) { … }
but avoid any serious work here.

Called after every change to input


ngOnChanges(changeRecord)
properties and before processing
{ … }
content or child views.

Called after the constructor,


ngOnInit() { … } initializing input properties, and the
first call to ngOnChanges.

Called every time that the input


properties of a component or a
ngDoCheck() { … } directive are checked. Use it to
extend change detection by
performing a custom check.
Called after ngOnInit when the
ngAfterContentInit() { …
component's or directive's content
}
has been initialized.

ngAfterContentChecked() { Called after every check of the


… } component's or directive's content.

Called after ngAfterContentInit


when the component's views and
ngAfterViewInit() { … }
child views / the view that a
directive is in has been initialized.

Called after every check of the


ngAfterViewChecked() { …
component's views and child views
}
/ the view that a directive is in.
Called once, before the instance is
ngOnDestroy() { … }
destroyed.

DEPENDENCY INJECTION DETAILS


CONFIGURATION

{ provide: MyService,
Sets or overrides the provider for
useClass:
MyService to the MyMockService class.
MyMockService }

{ provide: MyService, Sets or overrides the provider for


useFactory: myFactory MyService to the myFactory factory
} function.
{ provide: MyValue, Sets or overrides the provider for
useValue: 41 } MyValue to the value 41.

ROUTING AND NAVIGATION DETAILS

import { Routes, Import Routes,


RouterModule, … } from RouterModule, ... from
'@angular/router'; @angular/router.
const routes: Routes = [
{ path: '', component:
HomeComponent },
{ path: 'path/:routeParam',
component: MyComponent },
{ path: 'staticPath',
component: … },
{ path: '**', component: … },
{ path: 'oldPath', redirectTo:
Configures routes for the
'/staticPath' },
application. Supports static,
{ path: …, component: …, data:
parameterized, redirect, and
{ message: 'Custom' } }
wildcard routes. Also supports
]);
custom route data and resolve.

const routing =
RouterModule.forRoot(routes
);

<router-outlet></router-outlet>

Marks the location to load the


<router-outlet
component of the active route.
name="aux"></router-outlet>
<a routerLink="/path">
<a [routerLink]="[ '/path',
routeParam ]"> Creates a link to a different view
<a [routerLink]="[ '/path', { based on a route instruction
matrixParam: 'value' } ]"> consisting of a route path,
<a [routerLink]="[ '/path' ]" required and optional
[queryParams]="{ page: 1 }"> parameters, query parameters,
and a fragment. To navigate to a
root route, use the / prefix; for a
child route, use the ./prefix; for
<a [routerLink]="[ '/path'
a sibling or parent, use the ../
]" fragment="anchor">
prefix.

The provided classes are added


<a [routerLink]="[ '/path'
to the element when the
]"
routerLink becomes the
routerLinkActive="active">
current active route.

<a [routerLink]="[ '/path' The provided classes and


]" aria-current attribute are
routerLinkActive="active" added to the element when the
ariaCurrentWhenActive="page routerLink becomes the
"> current active route.
function canActivateGuard:
CanActivateFn =
(
route:
ActivatedRouteSnapshot, An interface for defining a
state: RouterStateSnapshot function that the router should
) => { … } call first to determine if it should
activate this component. Should
return a boolean|UrlTree or an
Observable/Promise that
resolves to a boolean|UrlTree.
{ path: …, canActivate:
[canActivateGuard] }

function canDeactivateGuard:
CanDeactivateFn<T> =
(
component: T,
route: An interface for defining a
ActivatedRouteSnapshot, function that the router should
state: RouterStateSnapshot call first to determine if it should
) => { … } deactivate this component after
a navigation. Should return a
boolean|UrlTree or an
Observable/Promise that
resolves to a boolean|UrlTree.
{ path: …, canDeactivate:
[canDeactivateGuard] }
function canActivateChildGuard:
CanActivateChildFn =
(
route:
ActivatedRouteSnapshot,
state: RouterStateSnapshot An interface for defining a
) => { … } function that the router should
call first to determine if it should
activate the child route. Should
return a boolean|UrlTree or an
Observable/Promise that
{ path: …,
resolves to a boolean|UrlTree.
canActivateChild:
[canActivateGuard],
children: … }

function resolveGuard implements


ResolveFn<T> =
(
route:
ActivatedRouteSnapshot, An interface for defining a
state: RouterStateSnapshot function that the router should
) => { … } call first to resolve route data
before rendering the route.
Should return a value or an
Observable/Promise that
resolves to a value.
{ path: …, resolve:
[resolveGuard] }
function canLoadGuard: CanLoadFn
=
(
route: Route An interface for defining a
) => { … } function that the router should
call first to check if the lazy
loaded module should be
loaded. Should return a
boolean|UrlTree or an
{ path: …, canLoad:
Observable/Promise that
[canLoadGuard],
resolves to a boolean|UrlTree.
loadChildren: … }

You might also like