Angular Signals & CLI Cheat Sheet
Quick reference guide for Angular: Signals, standalone components, control flow syntax (@if, @for), and CLI commands.
Angular is a platform and framework for building single-page client applications using TypeScript. Modern Angular features Signals for fine-grained reactivity and built-in control flow syntax (@if, @for).
Angular Signals Core API
Signals wrap a value and notify consumers when that value changes.
| API | Description | Access / Mutation Syntax |
|---|---|---|
signal(initialVal) | Create a reactive writable signal | Read: count() | Set: count.set(5) | Update: count.update(n => n + 1) |
computed(() => fn) | Create a read-only derived signal | Read: doubleCount() |
effect(() => fn) | Run side-effect when tracked signals change | Runs automatically in injection context |
input() | Declare a reactive component input | Read: title() |
output() | Declare an event emitter for component outputs | Emit: this.changed.emit(data) |
Standalone Component & Signals Syntax
import { Component, signal, computed, effect } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-counter',
standalone: true,
imports: [CommonModule],
template: `
<div class="card">
<h2>Counter Component</h2>
<p>Count: {{ count() }} | Double: {{ doubleCount() }}</p>
<button (click)="increment()">Increment</button>
</div>
`
})
export class CounterComponent {
// Writable signal
count = signal<number>(0);
// Derived computed signal
doubleCount = computed(() => this.count() * 2);
constructor() {
// Side effect tracking signal changes
effect(() => {
console.log(`Current count is: ${this.count()}`);
});
}
increment() {
this.count.update(c => c + 1);
}
}
Built-in Control Flow Syntax
Angular includes native block template syntax replacing *ngIf and *ngFor.
<!-- @if Block -->
@if (user(); as u) {
<p>Welcome back, {{ u.name }}!</p>
} @else if (isLoading()) {
<p>Loading user profile...</p>
} @else {
<p>Please log in.</p>
}
<!-- @for Block -->
<ul>
@for (item of items(); track item.id; let i = $index) {
<li>#{{ i + 1 }}: {{ item.name }}</li>
} @empty {
<li>No items found.</li>
}
</ul>
<!-- @switch Block -->
@switch (role()) {
@case ('admin') { <app-admin-panel /> }
@case ('editor') { <app-editor-panel /> }
@default { <app-user-panel /> }
}
Essential Angular CLI Commands
| Command | Action / Purpose |
|---|---|
ng new app-name | Create a new Angular application |
ng serve --open | Start development server on localhost:4200 |
ng generate component my-comp | Generate a standalone component |
ng generate service my-service | Generate an injectable service |
ng build --configuration production | Build optimized production bundle in dist/ |
ng test | Run Karma / Vitest unit tests |
Common Pitfalls & Tips
[!IMPORTANT] When reading a signal in TypeScript or HTML templates, you must call it as a function with parentheses
mySignal(). Omitting()returns the Signal object reference instead of its underlying value.
[!TIP] Always specify the
trackexpression in@forloops (e.g.,track item.id) for optimal DOM element recycling during re-renders.