| What | How |
|---|---|
| Definition |
@Component({
...
})
export class AppComponent {
mySignal : WritableSignal<String> = signal('Hello World !');
}
|
| reading |
mySignal() |
| setting a new value |
mySignal.set("Have a nice day")
|
| update |
mySignal.update(value => value + " !") |
| computed signal |
count : WritableSignal<number> = signal(0); doubleCount : Signal<number> = computed(() => count() * 2); |
| effect |
effect(() => {
console.log(`The current count is: ${count()}`);
});
|
| Use case | Template content of component | Angular code of component |
|---|---|---|
| display string value from @let |
@let message = Hello World ! |
|
| display string value from component | {{ message }} |
@Component({
...
})
export class AppComponent {
// default visibility is public
message : String = 'Hello World !';
}
|
| display string value from a signal in a component
Angular 16
|
{{ message() }} |
@Component({
...
})
export class AppComponent {
message : WritableSignal<String> = signal('Hello World !');
}
|
| input parameter for HTML tags (classic) | <button [disabled]="isFormValid">Save</button> |
@Component({
selector: 'echo',
...
})
export class EchoComponent {
isFormValid : boolean = true;
|
| pipe usage | {{ message | uppercase }} |
@Component({
selector: 'app',
...
})
export class AppComponent {
message : String = 'Hello World !';
}
|
| if, else, else-if
Angular 16
|
@if (a > b) {
{{ a }} is greater than {{ b }}
} @else if (b > a) {
{{ a }} is less than {{ b }}
} @else {
{{ a }} is equal to {{ b }}
}
|
@Component({
selector: 'app',
...
})
export class AppComponent {
a : number = 5;
b : number = 6;
}
|
| if, else, else-if as structural directives (classic) |
<div *ngIf="a > b">
{{ a }} is greater than {{ b }}
</div>
<div *ngIf="b > a">
{{ a }} is less than {{ b }}
</div>
<div *ngIf="a === b">
{{ a }} is equal to {{ b }}
</div>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
a : number = 5;
b : number = 6;
}
|
| switch
Angular 16
|
@switch (europeanCountry) {
@case ('Switzerland') {
<div>CHF</div>
}
@case ('Germany') {
<div>EUR</div>
}
@case ('Sweden') {
<div>SEK</div>
}
@default {
<div>EUR</div>
}
}
|
@Component({
selector: 'app',
...
})
export class AppComponent {
europeanCounter : String = "Switzerland";
}
|
| switch as structural directive (classic) |
<div [ngSwitch]="europeanCountry">
<div *ngSwitchCase="'Switzerland'"
CHF
</div>
<div *ngSwitchCase="'Germany'"
EUR
</div>
<div *ngSwitchCase="'Sweden'"
SEK
</div>
<div *ngSwitchDefault
EUR
</div>
</div>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
europeanCounter : String = "Switzerland";
}
|
| for-loop
Angular 17
|
<ul>
@for (item of items; track item) {
<li>{{ item }}</li>
}
</ul>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
items = ['Apple', 'Banana', 'Cherry'];
}
|
| for-loop as structural directive (old) |
<ul>
<li *ngFor="let item of items; trackBy: trackByFn">{{ item }}</li>
</ul>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
items = ['Apple', 'Banana', 'Cherry'];
}
|
| event firing in an HTML element (classic) |
<button (click)="doSomething()">Click me!</button>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
doSomething() : void {
// here we do something
}
}
|
| event firing in an HTML element with passing $event (classic) |
<button (click)="doSomething($event)">Click me!</button>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
doSomething(event: event) : void {
// here we do something
}
}
|
| two-way binding with HTML tags |
<div>
<input [(ngModel)]="firstNumber">
</div>
<div>
<input [(ngModel)]="secondNumber">
</div>
<div>
<button (click)="sum()">Add</button>
</div>
|
@Component({
selector: 'app',
imports: [ FormsModule ],
...
})
export class AppComponent {
firstNumber : number = 0;
secondNumber : number = 0;
|
| Use case | Template content of consumer | Template content of component | Angular code of consumer | Angular code of component |
|---|---|---|---|---|
| tag | <app></app> |
@Component({
selector: 'app',
standalone: true,
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
|
||
| input parameters (classic) | <echo [string]="Hello World !"/> |
{{ string }} |
not required
@Component({
selector: 'echo',
...
})
export class EchoComponent {
@Input() message : String = '';
}
required
@Component({
selector: 'echo',
...
})
export class EchoComponent {
@Input({required : true}) message : String! = '';
}
|
|
| input parameters (input signal)
Angular 16
|
<echo [string]="Hello World !"/> |
{{ string() }} |
not required
@Component({
selector: 'echo',
...
})
export class EchoComponent {
readonly string: InputSignal <string | undefined> input<string>();
}
required
@Component({
selector: 'echo',
...
})
export class EchoComponent {
readonly string: InputSignal <string>!;input.required<string>();
}
|
|
| two-way binding with custom tags |
<custom-slider [(value)]="volume"/>
|
@Component({
selector: 'foo',
...
})
export class CustomSlider {
volume : number = 50;
}
|
@Component({
selector: 'custom-selector',
...
})
export class CustomSlider {
@Input() value: number;
@Output() valueChange = new EventEmitter<number>();
}
|
|
| two-way binding with custom tags and model()
Angular 16
|
<custom-slider [(value)]="volume"/>
|
@Component({
selector: 'foo',
...
})
export class CustomSlider {
volume : number = 50;
}
|
@Component({
selector: 'custom-selector',
...
})
export class CustomSlider {
value = model(0);
}
|
|
| event firing on a component (classic) |
<alarm-demo>(myAlarm)=methodeToExecuteOnRaisedAlarm()"</alarm-demo>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
methodeToExecuteOnRaisedAlarm() : void {
// here we do something
}
}
|
@Component({
selector: 'alarm-demo',
...
})
export class AlarmDemoComponent {
@Output() myAlarm : EventEmitter<MyObject>> = new EventEmitter<MyObject>();
}
| |
| event firing on a component (with signals)
Angular 16
|
<alarm-demo>(myAlarm)=methodeToExecuteOnRaisedAlarm()"</alarm-demo>
|
@Component({
selector: 'app',
...
})
export class AppComponent {
methodeToExecuteOnRaisedAlarm() : void {
// here we do something
}
}
|
@Component({
selector: 'alarm-demo',
...
})
export class AlarmDemoComponent {
myAlarm : OutputEmitterRef<MyObject> = output<Book>();
}
| |
| dependency injection: by constructor provision: global |
@Component({
selector: 'app-root',
...
})
export class AppComponent {
constructor(private service: RandomNumberService) {}
}
|
@Injectable({
providedIn: 'root'
})
export class RandomNumberService {
randomNumber(): Number {
return Math.floor(Math.random() * 100);
}
}
|
||
| dependency injection of HttpClient by constructor provision: by module |
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Book } from './book';
@Injectable({
providedIn: 'root'
})
export class BookStoreService {
private apiUrl = 'https://api5.angular-buch.com';
constructor(private http: HttpClient) {}
getAll(): Observable<Book[]> {
return this.http.get<Book[]>(`${this.apiUrl}/books`);
}
getSingle(isbn: string): Observable<Book> {
return this.http.get<Book>(`${this.apiUrl}/books/${isbn}`);
}
remove(isbn: string): Observable<unknown> {
return this.http.delete(`${this.apiUrl}/books/${isbn}`);
}
}
|
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
HttpClientModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
|
||
| dependency injection: by inject()
Angular 16
|
@Component({
selector: 'app-root',
...
})
export class AppComponent {
service : RandomNumberService = inject(RandomNumberService);
}
|
@Injectable({
providedIn: 'root'
})
export class RandomNumberService {
randomNumber(): Number {
return Math.floor(Math.random() * 100);
}
}
|
||
| content projection with ng-content tutorial |
<custom-card>
Hello World !
</custom-card>
|
<div>
<ng-content></ng-content>
</div>
|
@Component({
selector: 'custom-card',
...
})
export class CustomCard {}
|
|
| attribute directive with constructor injection |
<p makeMeYellow>Hello World!</p>
|
import {Directive, ElementRef} from '@angular/core';
@Directive({
selector: '[makeMeYellow]',
})
export class MakeMeYellowDirective {
constructor(private el: ElementRef) {
this.el.nativeElement.style.backgroundColor = 'yellow';
}
}
|
||
| structural directive |
<p *makeMeYellow="isHighlighted">This text appears only if `isHighlighted` is true!</p>
|
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[makeMeYellow]'
})
export class MakeMeYellowDirective {
constructor(private templateRef: TemplateRef>any<, private viewContainer: ViewContainerRef) {}
@Input() set makeMeYellow(condition: boolean) {
if (condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
|
||
| attribute directive with @HostListener |
<p appHighlight>Highlight me!</p>
|
import {Directive, ElementRef, HostListener} from '@angular/core';
@Directive({
selector: '[appHighlight]',
})
export class HighlightDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight('');
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
|
||
| attribute directive with @HostBinding and @HostListener (to convert to smaller letters) |
<label>E-Mail: </label>
<input type="text" chLowerCase/>
|
@Directive({selector: '[chLowerCase]'})
export class LowerCaseDirective {
@HostBinding() value = '';
@HostListener('change', ['$event']) onChange($event: Event){
this.value = ($event.target as HTMLInputElement).value.toLowerCase();
}
}
|
||
| Pipe |
<p>{{ 'Angular' | reverse }}</p>
|
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse' // name of the pipe
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
|
||
| Pipe with a parameter |
<p>{{ 'Hello ' | repeat:3 }}</p> // Output: Hello Hello Hello
<p>{{ 'Angular ' | repeat:2 }}</p> //Output: Angular Angular
|
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'repeat'
})
export class RepeatPipe implements PipeTransform {
transform(value: string, times: number = 1): string {
return value.repeat(times);
}
}
|
| Use case | code |
|---|---|
| new version
14
|
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { AppComponent } from './app.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes)]
});
|
| old version |
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
|