Angular Signals & CLI Cheat Sheet

Quick reference guide for Angular: Signals, standalone components, control flow syntax (@if, @for), and CLI commands.

Modern Frontend
angular
frontend
typescript

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.

Table
APIDescriptionAccess / Mutation Syntax
signal(initialVal)Create a reactive writable signalRead: count() | Set: count.set(5) | Update: count.update(n => n + 1)
computed(() => fn)Create a read-only derived signalRead: doubleCount()
effect(() => fn)Run side-effect when tracked signals changeRuns automatically in injection context
input()Declare a reactive component inputRead: title()
output()Declare an event emitter for component outputsEmit: this.changed.emit(data)

Standalone Component & Signals Syntax

typescript
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.

html
<!-- @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

Table
CommandAction / Purpose
ng new app-nameCreate a new Angular application
ng serve --openStart development server on localhost:4200
ng generate component my-compGenerate a standalone component
ng generate service my-serviceGenerate an injectable service
ng build --configuration productionBuild optimized production bundle in dist/
ng testRun 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 track expression in @for loops (e.g., track item.id) for optimal DOM element recycling during re-renders.