Angular Training Material
Angular Training Material
Angular Training Material
Angular Modules :
GitHub Repository :
https://github.com/DeborahK/Angular-GettingStarted
JS Language Specification
ECMAScript(ES)
ES5
ES2015 -> must be transpiled to ES5
Select a Language
ES5 -> Runs in browser, no compile req
ES2015 -> lot of features but must be transpiled
TypeScript -> Open Source Language
Superset of JS,
Transpiles to plain JS
Strongly Typed(by TS type definition files (*.d.ts))
Class based object orientation
Setup Environment :
For Installing npm
Install Node from https://www.npmjs.com
https://github.com/DeborahK/Angular-GettingStarted
Modules :
ES 2015 Modules -
are code files that import or export something
product.ts
export class Product{
product-list.ts
import {Product} from
'./product'
Angular Modules -
code files that organize the app into cohesive blocks
of functionality
Angular is Modular
import {Component} from '@angular/core';-> angular Library Module
Decorator
It is a function that adds metadata to a class, members or method arguments.
Component is a decorator
{{ }} is for binding
@Component({
selector: 'pm-root' -> used in HTML
template:<h1>{{pagetitle}}</h1>
})
In app.module.ts
@NgModule({
declarations:[AppComponent],
imports:[],
providers:[],
bootstrap:[AppComponent]
})
Component CheckList :
Class -> Code
Decorator -> Metadata
Import what we need
Building a Template :
Template
<h1>{{pageTitle}}</h1>
Template Checklist
Inline Template
Linked Template
Use component as directive
Interpolation Checklist
one way binding, uses curly braces
Strutural Directives
prefix with an *
*ngIf : evaluates true or false so an element is added or removed
*ngFor : define local variable with Let and use of
Interpolation
{{ }}
Property binding
<img [src]='product.imageurl'>
Event binding
showImage: boolean = false;
toggleImage() : void {
this.showImage = !this.showImage;
}
<button class='btn btn-primary' (click) = toggleImage()>
2 way binding
[(ngModel)] = 'listFilter'
[] is property binding, () is event binding
ngModel belongs to @angular/forms
Pipes(|)
transform bound properties before display
built in : date, number, decimal, currency, json, slice.
custom pipes
Defining Interfaces
ES5,ES2015 do not support interfaces
only TypeScript supports interfaces
toggleImage() : void {
}
}
style :
@Component({
styleUrls :
@Component({
styles: ['./product-list.component.css']
})
Component Lifecycle :
Create -> Render -> Create and Render Childs -> process -> destroy
@Pipe({
name: 'ConvertToSpaces'
})
Filtering a List
Angular team recommends placing the filtering and sorting logic in the
component itself.
In product-list.component.ts
_listFilter: string;
get listFilter() : string
{
return this._listFilter;
}
set listFilter(value: string)
{
this._listFilter = value;
this.filteredProducts = this.listFilter ?
this.performFilter(this.listFilter): this.products;
}
filteredProducts: IProduct[];
In product-list.component.html
*ngFor let product of filteredProducts;
In product-list.component.html
change <td>{{product.starRating}}</td>
to
<td><pm-star></pm-star></td>
Declare in app.module.ts
In product-list.component.html
<td><pm-star [rating]='product.starRating'></pm-star></td>
In product-list.component.html
<td><pm-star (ratingClicked)='OnRatingClicked($event)'></pm-star></td>
Service is a class used for features independent from any particular component.
encapsulate external interactions.
Service
export class myservice{}
Component
constructor(private _myservice){}
Building a Service
@Injectable()
Register a Service
Registered in Component
Injectable to component and its children
Registered in Angular Module
Injectable to anywhere in app
In app.component.ts
Injecting a service
A singleton Instance of the service is injected into the component through
the component constructor.
ngOnInit() : void {
this.products = this._productService.getProducts();
}
@Injectable()
Subscribe to an observable
In Service
getProducts(): Observable<IProduct[]>{
return this._http.get<IProduct[]>(this._productUrl);
}
In Component
ngOnInit() : void {
this._productService.getProducts()
.subscribe(products => {this.products = products;
this.filteredProducts = this.products;},
error => this.errorMessage = <any>error);
when the browsers url changes, angular looks for route definition matching the
path segment.then, angular loads the ProductListComponent Template.
{path: 'products', component: ProductListComponent}
localhost:3000/products
Menu
Home Product List <a routerlink="/products">Product List</a>
Configuring Routes
RouterModule.forRoot([
{path: 'products', component: ProductListComponent},
{path: 'products/:id', component: ProductDetailComponent},
{path: 'welcome', component: WelcomeComponent},
{path: '', redirectTo: 'welcome', pathmatch: 'full'},
{path: '**', component: PageNotFoundComponent}
])
<a [routerLink]="['/welcome']">
let id = this._route.snapshot.paramMap.get('id');
this.pageTitle += `: ${ id }`;
this.product = {
"productId": parseInt(id)}
}
Navigate to a route from code
constructor(private _router: Router) { }
onBack(): void {
this._router.navigate(['products']);
let id = route.url[1].path;
this._router.navigate(['/products']);
return false;
return true;
}
}
Angular Modules
A class with NgModule decorator. Organizes our code into blocks.
Extends app with capabilities from external libraries.
For Example :
1)app module imports the system modules we need
BrowserModule, FormsModule, RouterModule etc.
Bootstrap Array
bootstrap: [AppComponent]
a)every app must bootstrap atleast one component, the root app component.
b)Bootstrap Array should only be used in root application module,AppModule.
Declarations Array
a)Every component, directive, pipe we create must belong to one and only one
angular module.
b)only declare components, directives and pipes
c)never redeclare from another module.
Exports Array
exports: []
a)export any component, directive or pipe.
b)never export a service
Imports Array
imports: []
we can import an angular module, 3rd party module etc
providers Array
a)providers:[] allows us to register services at module level
b)service added to the providers array is registered at root of the app.
c)don't add services to providers array of shared module.instead build a
module for services and import into appmodule.
d)Routing guards must be added to providers array of an angular module.
Feature Module
Shared Module
Commonly used modules can be kept in shared modules and exported.
Angular CLI
A command line interface for angular.
purpose is to build an angular app, execute the app, run tests and
deployment.
npm install -g @angular/cli
ng new Hello-World
Creates a New App
ng serve
used to run the app
ng generate
used to generate a component, class, service etc
ng test and ng e2e are used for unit tests and end to end tests.
https://github.com/jmcooper/angular-fundamentals-files
rm -rf node_modules
In app.module.ts
bootstrap: [AppComponent]
In app.component.ts
selector: 'app-root'
Components
a)template url is relative to component.
In Child Component :
export class EventThumbnailComponent {
@Input() event:any;
}
In Parent Component :
<eventthumbnail [event]="event1" ></eventthumbnail>
export class EventListComponent {
event1 = {}
}
pass data from child component to Parent component
In Child Component :
export class EventThumbnailComponent {
@Output() eventclick = new EventEmitter();
onButtonClick(): void{
this.eventclick.emit("foo");
}
}
In Parent Component :
handleEventClicked(data){
console.log('received:', data);
}
}
In Parent Component
<eventthumbnail #thumbnail ></eventthumbnail>
<p>{{thumbnail.someproperty}}</p>
In Child Component :
export class EventThumbnailComponent {
template:`<h2>{{user.name}}</h2>
<image [src]= "user.imageUrl"></image>
<button (click)="doSomething()"></button>`
using hidden :
template:`
<div [hidden]="!event?.name">
<h2>{{event?.name}}</h2>
</div>`
using ngSwitch
<div [ngSwitch]="event?.time">
<span *ngSwitchCase="'8:00 am'"> Early Start</span>
<span *ngSwitchCase="'10:00 am'"> Early Start</span>
<span *ngSwitchDefault> Normal Start</span>
</div>
GetStyleClasses(){
if(this.event && this.event.time === '8:00 am')
return 'green bold'
return ''
}
GetEarlyStyle(): any{
if(this.event && this.event.time === '8:00 am')
return {color:'#003300', 'font-weight': 'bold'}
return {}
}
Services
Adding a 3rd Party Service
1)In appcomponent :
template:
`<router-outlet></router-outlet>`
Linking to Routes
In HTML Template
<div [routerLink]="['/events', event.id]">
</div>
In routes.ts :
In Component.ts
imports:[
CommonModule,
RouterModule.forChild(userroutes)
]
the above are different from app module.
In a given component.ts
<collapsible-well [title]="session.name">
//html content
</collapsible-well>
--------------------------------------------------------------------
2 types of forms technologies
2)Reactive Forms
use a component's template
create a form model in typescript(it must be in sync with template)
Unit Test Against Form Model
Validation in Form Model
Angular Versions :
RC 4 and earlier -> old forms API bootstrap a component
RC5 to 2.0 -> New Forms API bootstraps a NgModule
<h3>Angular 2 Forms</h3>
<form #form="ngForm">
<input type="text" placeholder="Name" name="name" ngModel>
<button type="submit">Ok</button>
</form>
{{ form.pristine }}
Adding Bootstrap
http://getbootstrap.com/docs/4.1/getting-started/introduction/
In home.component.html
<div class="container">
<h3>Angular 2 Forms</h3>
<form #form="ngForm" novalidate>
<div class="form-group">
<label> First Name</label>
<input type="text" class="form-control" required name="firstname"
ngModel>
</div>
<button class="btn btn-primary" type="submit">Ok</button>
</form>
</div>
Here create a div class called container, change button type to btn bth-primary
input type of class form-control.
Note : Each control should have a name and ngModel should be specified
for angular to access or validate it.
Summary :
ngForm, ngModel directives
NoValidate
BootStrap Styling
Checkbox, radiobutton, select-options using *ngFor
Browser Inconsistencies for differnet controls
Binding to Model
In HTML
<input type="text" class="form-control" name="firstname" [ngModel] =
"model.firstName"
(ngModelChange) = "model.firstName=$event">
In Component.ts
model = new Employee("Darla", "Smith");
In Component.ts
firstNameToUpperCase(value: string){
}
ng-untouched
ng-touched -> when a field loses focus
ng-pristine
ng-dirty
ng-valid
ng-invalid
submitForm(form: NgForm){
this.formposter.postEmployeeForm(this.model).subscribe(
data => console.log('success', data),
err => console.log('error', err)
)
}
In HTML Template :
<form #form="ngForm" (submit)="submitForm(form)" novalidate>
In Service
this.formposter.getLanguages().subscribe(
data => this.languages = data.languages,
err => console.log('error', err)
)
In service
getLanguages() : Observable<any>{
return this.http.get('http://localhost:3100/get-languages')
.map(this.extractLanguages).catch(this.handleError);
}
-----------------------------------------------------------------------
if(req.method.toLowerCase() == 'post'){
processForm(req, res);
return;
}
if(req.method.toLowerCase() == 'get'){
var data = {data:{languages:['English', 'Spanish', 'German', 'Other']}};
var responseData = JSON.stringify(data);
res.end(responseData);
console.log("get: ", responseData);
return;
}
res.end();
});
};