Luis Aviles
Google Developer Expert in Angular. Web and Open Source lover. Speaker/Trainer, photography and Astrophotography enthusiast. @angularBolivia and #NgBolivia organizer.
Luis Aviles
@luixaviles
How can I start?
npm install -g @angular/cli@latest
ng new <project-name> [options]
ng new my-project-name --skip-install
yarn install
cd my-project-name
ng g component my-new-component
ng g directive my-new-directive
ng g pipe my-new-pipe
Pipes
<p>The hero's birthday is {{ birthday | date }}</p>
Built-in pipes
Built-in pipes
Creating custom Pipes
ng g pipe my-custom-pipe
Creating custom Pipes
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'myCustomPipe'
})
export class MyCustomPipe implements PipeTransform {
transform(value: any, args?: any): any {
// return something.
}
}
ng g service my-new-service
ng g class my-new-class
ng g interface my-new-interface
ng g enum my-new-enum
ng g module my-module
Using Components
Displaying data
interpolation
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<h2>My name is: {{name}}</h2>
`
})
export class AppComponent {
title = 'Welcome';
name = 'Luis';
}
property binding
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<div>
<h1 [innerHTML]="title"></h1>
<input type="text" [value]="text">
<div>{{text}}</div>
</div>
`
})
export class AppComponent {
title = 'Welcome';
text = 'Luis';
}
binding to user events
import { Component } from '@angular/core';
@Component({
selector: 'click-me',
template: `
<button (click)="onClickMe()">Click me!</button>
{{clickMessage}}
`
})
export class AppComponent{
clickMessage = '';
onClickMe() {
this.clickMessage = 'You are my hero!';
}
}
$event object
import { Component } from '@angular/core';
@Component({
selector: 'click-me',
template: `
<input (keyup)="onKey($event)">
<p>{{values}}</p>
`
})
export class AppComponent{
values = '';
onKey(event:any) {
this.values += event.target.value + ' | ';
}
}
Dependency Injection(DI)
Dependency Injection
Dependency Injection
// hero-list.component.ts
import { Component } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'hero-list',
template: `
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
`
})
export class HeroListComponent {
heroes: Hero[];
constructor(heroService: HeroService) {
this.heroes = heroService.getHeroes();
}
}
Dependency Injection
// hero.service.ts
import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes() { return HEROES; }
}
No Dependency Injection
// hero-list.component.ts
import { Component } from '@angular/core';
import { HEROES } from './mock-heroes';
@Component({
selector: 'hero-list',
template: `
<div *ngFor="let hero of heroes">
{{hero.id}} - {{hero.name}}
</div>
`
})
export class HeroListComponent {
heroes = HEROES;
}
Promises
resolve()
// hero.service.ts
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes(): Promise<Hero[]> {
return Promise.resolve(HEROES);
}
}
then() method
// app.component.ts
@Component({
// More code goes here
})
export class AppComponent implements OnInit {
heroes: Hero[];
constructor(private heroService: HeroService) { }
getHeroes(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes);
}
ngOnInit(): void {
this.getHeroes();
}
}
reject()
// hero.service.ts
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes(): Promise<Hero[]> {
return Promise.reject('Cannot connect with the server');
}
}
Error catch
// app.component.ts
@Component({
// More code goes here
})
export class AppComponent implements OnInit {
heroes: Hero[];
constructor(private heroService: HeroService) { }
getHeroes(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes);
.catch(error => {
console.error('Error', error);
});
}
ngOnInit(): void {
this.getHeroes();
}
}
HTTP Services
class HttpClient {
request(first: string|HttpRequest<any>, url?: string, options: {...}):
Observable<any>
delete(url: string, options: {...}): Observable<any>
get(url: string, options: {...}): Observable<any>
head(url: string, options: {...}): Observable<any>
jsonp<T>(url: string, callbackParam: string): Observable<T>
options(url: string, options: {...}): Observable<any>
patch(url: string, body: any|null, options: {...}): Observable<any>
post(url: string, body: any|null, options: {...}): Observable<any>
put(url: string, body: any|null, options: {...}): Observable<any>
}
// app.module.ts:
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
// Import HttpClientModule from @angular/common/http
import {HttpClientModule} from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
// Include it under 'imports' in your application module
// after BrowserModule.
HttpClientModule,
],
})
export class MyAppModule {}
@Component(...)
export class MyComponent implements OnInit {
results: string[];
// Inject HttpClient into your component or service.
constructor(private http: HttpClient) {}
ngOnInit(): void {
// Make the HTTP request:
this.http.get('/api/items').subscribe(data => {
// Read the result field from the JSON response.
this.results = data['results'];
});
}
}
Components
Interaction/ Communication
Pass data from parent to child
import { Component } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'hero-parent',
template: `
<h2>{{master}} controls {{heroes.length}} heroes</h2>
<hero-child [hero]="heroObject">
</hero-child>
`
})
export class HeroParentComponent {
heroObject = new Hero();
}
import { Component, Input } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'hero-child',
template: `
<h3>{{hero.name}} says:</h3>
<p>I, {{hero.name}}, am at your service</p>
`
})
export class HeroChildComponent {
@Input() hero: Hero;
}
Pass data from parent to child
Parent listens child event
import { Component } from '@angular/core';
@Component({
selector: 'vote-taker',
template: `
<h2>Should mankind colonize the Universe?</h2>
<my-voter [name]="voter" (onVoted)="onVoted($event)">
</my-voter>
`
})
export class VoteTakerComponent {
voter: 'Foo Bar';
onVoted(agreed: boolean) {
console.log('Voter agrees: ', agreed);
}
}
Parent listens child event
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'my-voter',
template: `
<h4>{{name}}</h4>
<button (click)="vote(true)" [disabled]="voted">Agree</button>
<button (click)="vote(false)" [disabled]="voted">Disagree</button>
`
})
export class VoterComponent {
@Input() name: string;
@Output() onVoted = new EventEmitter<boolean>();
voted = false;
vote(agreed: boolean) {
this.onVoted.emit(agreed);
this.voted = true;
}
}
Routing & Navigation
Application Navigation Model
RouterOutlet
<router-outlet></router-outlet>
Forms
<input [(ngModel)]="username">
References & resources
By Luis Aviles
Angular Fundamentals
Google Developer Expert in Angular. Web and Open Source lover. Speaker/Trainer, photography and Astrophotography enthusiast. @angularBolivia and #NgBolivia organizer.