CLI
Generate
Using dash case
ng generate component new-custom-component
Directive
Additional behavior to DOM elements in HTML
Components
Used with a template.
NgModel
Adds two-way data binding to an HTML form element.
Method 1 – Without NgModel
<label for="without">without NgModel:</label>
<input
[value]="js_var"
(input)="js_var = getValue($event)"
id="without"
/>
Method 2 – With NgModel
<label for="example-ngModel">[(ngModel)]:</label>
<input [(ngModel)]="js_var" id="example-ngModel" />
Method 3 – With NgModelChange Event
<label for="example-change">(ngModelChange)="...name=$event":</label>
<input
[ngModel]="js_var"
(ngModelChange)="js_var = $event"
id="example-change"
/>
Method 4 – additional changes for variable
<label for="example-uppercase"
>(ngModelChange)="setUppercaseName($event)"
<input
[ngModel]="js_var"
(ngModelChange)="setUppercaseName($event)"
id="example-uppercase"
/>
</label>
NgClass
Adds and removes a set of CSS classes.
// CSS
.course {
font-weight: bold;
font-size: x-large;
}
.helpful {
color: red;
}
.study,
.modified {
font-family: "Brush Script MT", cursive;
font-size: 2rem;
}
// HTML
<div class="helpful study course">Helpful study course</div>
// Turn css class/property based on true or false
<div [ngClass]="{ helpful: false, study: false, course: false }">
Study course
</div>
NgClass using JS variable
currentClasses: Record<string, boolean> = {};
// HTML
<div [ngClass]="currentClasses">
Check style based on CSS
</div>
NgStyle
Set multiple inline styles simultaneously, based on the state of the component.
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">
This div is x-large or smaller.
</div>
<div [style.color]="isSpecial ? 'red' : 'blue'">
This div is red or blue.
</div>
NgStyle using JS variable
<div [ngStyle]="currentStyles">
This div is initially italic, normal weight, and extra large (24px).
</div>
Build-in structural directives
NgIf
To add or remove an element, bind *[ngIf](<https://angular.io/api/common/NgIf>)
to a condition expression such as isActive
,or check if variable is null.
<app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>
ng-template
defines a template that is not rendered by default.
<ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template>
class.hidden
<div [class.hidden]="!isSpecial">Show with class</div>
NgFor
static items: Item[] = [
new Item(
0,
'Teapot',
'stout'
),
new Item(1, 'Lamp', 'bright'),
new Item(2, 'Phone', 'slim' ),
new Item(3, 'Television', 'vintage' ),
new Item(4, 'Fishbowl')
];
<div class="box">
<div *ngFor="let item of items">{{ item.name }}</div>
</div>
<div *ngFor="let item of items; let i = index">
{{ i + 1 }} - {{ item.name }}
</div>
TrackBy
Reduce the number of calls your application makes to the server by tracking changes to an item list. With the *[ngFor](<https://angular.io/api/common/NgForOf>)
trackBy
property, Angular can change and re-render only those items that have changed, rather than reloading the entire list of items.
??
ng-container
Hosting a directive without a DOM element
Use [<ng-container>](<https://angular.io/api/core/ng-container>)
when there’s no single element to host the directive.
<p>
I turned the corner
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
ng-container with forms
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
NgSwitch
// Javascript
num: number= 0;
// HTML
<div class='card'>
<div class='card-header'>
ngSwitch Example
</div>
<div class="card-body">
Input string : <input type='text' [(ngModel)]="num" />
<div [ngSwitch]="num">
<div *ngSwitchCase="'1'">One</div>
<div *ngSwitchCase="'2'">Two</div>
<div *ngSwitchCase="'3'">Three</div>
<div *ngSwitchCase="'4'">Four</div>
<div *ngSwitchCase="'5'">Five</div>
<div *ngSwitchDefault>This is Default</div>
</div>
</div>
</div>
Router
Basic
Associate a URL path with a component
Step 1 – add path in RouterModule
@NgModule({
imports: [
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
])
],
})
Step 2 – for the hyperlink add routeLink
<a
[title]="product.name + ' details'"
[routerLink]="['/products', product.id]">
{{ product.name }}
</a>
Step 3 – Implement route component in JS
import { Component, OnInit } from '@angular/core';
**import { ActivatedRoute } from '@angular/router';
import { Product, products } from '../products';**
export class ProductDetailsComponent implements OnInit {
**product: Product | undefined;**
constructor( **private route: ActivatedRoute** ) { }
ngOnInit(): void {
// First get the product id from the current route.
**const routeParams = this.route.snapshot.paramMap;
const productIdFromRoute = Number(routeParams.get('productId'));**
// Find the product that correspond with the id provided in route.
**this.product = products.find(product => product.id === productIdFromRoute);**
}
}
Step 4 – Use ngIf in component HTML
<div *ngIf="product">
<h3>{{ product.name }}</h3>
<h4>{{ product.price | currency }}</h4>
</div>
Lazy Loading
https://angular.io/guide/lazy-loading-ngmodules
Pipe
Use pipes to transform strings, currency amounts, dates, and other data for display
https://angular.io/guide/pipes
Dependency Injection
allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.
When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry.
Basic – create service
ng generate service cart
cart.service.ts
export class CartService {
items: Product[] = [];
addToCart(product: Product) {
this.items.push(product);
}
}
In component
import { CartService } from '../cart.service';
export class ProductDetailsComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private cartService: CartService
) { }
addToCart(product: Product) {
this.cartService.addToCart(product);
window.alert('Your product has been added to the cart!');
}
}
RxJS
Reactive Extensions for JavaScript
makes it easier to compose asynchronous or callback-based code
- Converting existing code for async operations into observables
- Iterating through the values in a stream
- Mapping values to different types
- Filtering streams
- Composing multiple streams
https://angular.io/guide/rx-library
Communicating with backend services
communicate with a server over the HTTP protocol
- The ability to request typed response objects
- Streamlined error handling
- Testability features
- Request and response interception
Basic
app.module.ts
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
HttpClientModule,
])
]
})
Inject the [HttpClient](<https://angular.io/api/common/http/HttpClient>)
service into your service
cart.service.ts
import { HttpClient } from '@angular/common/http';
export class CartService {
items: Product[] = [];
constructor(private http: HttpClient) {}
getShippingPrices() {
return this.http.get<{type: string, price: number}[]>('/assets/shipping.json');
}
Get the data
shipping.component.ts
import { Observable } from 'rxjs';
import { CartService } from '../cart.service';
export class ShippingComponent implements OnInit {
shippingCosts!: Observable<{ type: string, price: number }[]>;
constructor(private cartService: CartService) { }
ngOnInit(): void {
this.shippingCosts = this.cartService.getShippingPrices();
}
}
Use async pipe
shipping.component.html
<div class="shipping-item" *ngFor="let shipping of shippingCosts | async">
<span>{{ shipping.type }}</span>
<span>{{ shipping.price | currency }}</span>
</div>
Reactive forms
provide a model-driven approach to handling form inputs whose values change over time
https://angular.io/guide/reactive-forms
Basic
add FormsModule into appModule
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
ReactiveFormsModule
]
})
export class AppModule { }
cart.component.ts
import { FormBuilder } from '@angular/forms';
export class CartComponent implements OnInit {
checkoutForm = this.formBuilder.group({
name: '',
address: ''
});
constructor(private formBuilder: FormBuilder) { }
onSubmit(): void {
// Process checkout data here
this.items = this.cartService.clearCart();
console.warn('Your order has been submitted', this.checkoutForm.value);
this.checkoutForm.reset();
}
}
cart.compoent.html
<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
<div>
<label for="address">
Address
</label>
<input id="address" type="text" formControlName="address">
</div>
<button class="button" type="submit">Purchase</button>
</form>