--- name: modern-angular-implementation description: Implement Angular 18+ features: Signals, standalone components, @defer blocks, SSR, zoneless change detection, new control flow syntax, and Material 3 integration. --- # Modern Angular Implementation Skill ## Angular Signals ### Basic Signals ```typescript import { Component, signal, computed, effect } from '@angular/core'; @Component({ selector: 'app-counter', standalone: true, template: `
Double: {{ double() }}
` }) export class CounterComponent { // Writable signal count = signal(0); // Computed signal (auto-updates) double = computed(() => this.count() * 2); constructor() { // Effect (side effects) effect(() => { console.log('Count changed:', this.count()); }); } increment() { this.count.update(n => n + 1); // or: this.count.set(this.count() + 1); } } ``` ### Signal Store Pattern ```typescript @Injectable({ providedIn: 'root' }) export class UserStore { // Private state signal private state = signal<{ users: User[]; loading: boolean; error: string | null; }>({ users: [], loading: false, error: null }); // Public computed selectors readonly users = computed(() => this.state().users); readonly loading = computed(() => this.state().loading); readonly error = computed(() => this.state().error); readonly userCount = computed(() => this.users().length); // Actions async loadUsers() { this.state.update(s => ({ ...s, loading: true })); try { const users = await this.http.getFailed to load video player
} ``` ### Strategic Deferment ```typescriptNo items found
} ``` ### @switch (replaces *ngSwitch) ```typescript // OLDLoading...
Error occurred
Success
Loading...
} @case ('error') {Error occurred
} @default {Success
} } ``` ### Combined Control Flow ```typescript @if (users.length > 0) {Loading users...
} ``` ## Server-Side Rendering (SSR) ### Enable SSR ```bash # Add SSR to existing project ng add @angular/ssr # Or create new project with SSR ng new my-app --ssr ``` ### SSR Configuration ```typescript // app.config.ts import { ApplicationConfig } from '@angular/core'; import { provideClientHydration } from '@angular/platform-browser'; export const appConfig: ApplicationConfig = { providers: [ provideClientHydration() // Enable hydration ] }; ``` ### SSR-Safe Code ```typescript import { Component, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({...}) export class MapComponent { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} ngOnInit() { // Only run in browser if (isPlatformBrowser(this.platformId)) { this.initializeMap(); this.loadGoogleMapsAPI(); } } private initializeMap() { // Browser-specific code const map = new google.maps.Map(document.getElementById('map')); } } ``` ### Transfer State (Avoid Duplicate Requests) ```typescript import { Component, makeStateKey, TransferState } from '@angular/core'; const USERS_KEY = makeStateKeyBeautiful Material Design 3 components