CodeScript

Angular Cheat Sheet

Essential Angular cheat sheet covering CLI schematics, Signals, control flow syntax, dependency injection, routing, reactive forms, and RxJS integration.

1. Angular CLI & Workspace Setup

Commands for project initialization, build configurations, and schematics.

CLI Commands

npm install -g @angular/cli            # Install CLI globally
ng new my-app --ssr --style=scss      # Create app with SSR and SCSS
ng serve --open --port 4200            # Run dev server
ng build --configuration production    # Production bundle output to dist/
ng test                                # Execute unit tests
ng e2e                                 # Execute end-to-end tests
ng update @angular/cli @angular/core   # Automated workspace migration

Schematics Generators

ng g c features/user --standalone     # Standalone Component
ng g s services/auth                   # Injectable Service
ng g p shared/pipes/truncate           # Custom Pipe
ng g d shared/directives/highlight       # Custom Directive
ng g g guards/auth                     # Functional Guard (CanActivate, CanMatch)
ng g interceptor core/auth             # Functional HTTP Interceptor
ng g resolver resolvers/user-data      # Route Data Resolver
ng g environments                      # Generate environment.ts configuration files

2. Standalone Architecture & Signals API

Modern component configuration, Signal state primitives, and Signal inputs/outputs.

import { Component, signal, computed, effect, input, output, model, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-user-card',
  standalone: true,
  imports: [],
  templateUrl: './user-card.component.html',
  styleUrl: './user-card.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserCardComponent {
  // Signal Inputs & Outputs
  userId = input.required<string>();                     // Required input signal
  role = input<string>('guest');                         // Input signal with default fallback
  selected = model<boolean>(false);                       // Two-way binding signal input ([(selected)])
  profileUpdated = output<UserProfile>();                 // Output event emitter

  // Writable & Computed Signals
  count = signal<number>(0);                             // Writable signal state
  doubleCount = computed(() => this.count() * 2);        // Pure derived computed state

  constructor() {
    // Side Effects
    effect((onCleanup) => {
      const timer = setTimeout(() => console.log(this.count()), 1000);
      onCleanup(() => clearTimeout(timer));              // Effect cleanup callback
    });
  }

  mutateState() {
    this.count.set(5);                                   // Direct override
    this.count.update(c => c + 1);                       // Value modification relative to prior state
  }
}

3. Built-in Control Flow

Native template control syntax (`@if`, `@for`, `@switch`).

@if (isLoggedIn()) {
  <p>Welcome, {{ user().name }}</p>
} @else if (isPending()) {
  <p>Authenticating...</p>
} @else {
  <button (click)="login()">Sign In</button>
}

@for (item of items(); track item.id; let i = $index, count = $count) {
  <div>{{ i + 1 }}/{{ count }}: {{ item.name }}</div>
} @empty {
  <p>No items registered.</p>
}

@switch (userRole()) {
  @case ('admin') { <app-admin-panel /> }
  @case ('editor') { <app-editor-panel /> }
  @default { <app-viewer-panel /> }
}

4. Deferrable Views (`@defer`)

Declarative template lazy-loading with triggers.

@defer (on viewport; prefetch on idle) {
  <app-heavy-chart [data]="chartData()" />
} @placeholder (minimum 500ms) {
  <div class="skeleton">Chart Placeholder</div>
} @loading (after 100ms; minimum 1s) {
  <app-spinner />
} @error {
  <p>Failed to load component bundle.</p>
}

// Triggers: on idle, on viewport, on interaction,
// on hover, on timer(2s), when conditionSignal()

5. Dependency Injection & Hierarchical Injectors

Services, functional `inject()`, InjectionTokens, and scoping.

import { Injectable, inject, InjectionToken, ApplicationConfig } from '@angular/core';
import { HttpClient } from '@angular/common/http';

export const API_CONFIG = new InjectionToken<ApiConfig>('API_CONFIG');

@Injectable({
  providedIn: 'root'                                   // Singleton service available application-wide
})
export class AuthService {
  private config = inject(API_CONFIG);                 // Functional dependency injection
  private http = inject(HttpClient);
}

// Provider Configurations in app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    { provide: API_CONFIG, useValue: { baseUrl: 'https://api.domain.com' } },
    { provide: LoggerService, useClass: CustomLoggerService }
  ]
};

6. Routing, Functional Guards & Resolvers

Routes setup, route parameters, functional protection, and data resolvers.

import { Routes, CanActivateFn, ResolveFn, inject, Router } from '@angular/router';

export const authGuard: CanActivateFn = (route, state) => {
  const auth = inject(AuthService);
  const router = inject(Router);
  return auth.isLoggedIn() ? true : router.parseUrl('/login');
};

export const userResolver: ResolveFn<UserData> = (route) => {
  return inject(UserService).getUser(route.paramMap.get('id')!);
};

export const routes: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  {
    path: 'dashboard',
    loadComponent: () => import('./dashboard/dashboard.component').then(m => m.DashboardComponent),
    canActivate: [authGuard]
  },
  {
    path: 'user/:id',
    loadComponent: () => import('./user/user.component').then(m => m.UserComponent),
    resolve: { user: userResolver }
  }
];

7. Functional HTTP Interceptors

Intercept requests and responses within HTTP pipelines.

import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authToken = inject(AuthService).getToken();
  const authReq = req.clone({
    setHeaders: { Authorization: `Bearer ${authToken}` }
  });
  return next(authReq);
};

8. Custom Directives

Host listeners and style bindings.

import { Directive, HostBinding, HostListener, input } from '@angular/core';

@Directive({ selector: '[appHighlight]', standalone: true })
export class HighlightDirective {
  highlightColor = input<string>('yellow', { alias: 'appHighlight' });

  @HostBinding('style.backgroundColor') bgColor = '';

  @HostListener('mouseenter') onMouseEnter() {
    this.bgColor = this.highlightColor() || 'yellow';
  }
  @HostListener('mouseleave') onMouseLeave() {
    this.bgColor = '';
  }
}

9. Custom Pipes

Pure template data transformation.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'truncate', standalone: true, pure: true })
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 20, trail = '...'): string {
    if (!value) return '';
    return value.length > limit ? value.substring(0, limit) + trail : value;
  }
}
// Usage: {{ text() | truncate:50:'...' }}

10. Strictly Typed Reactive Forms

Typed form controls and built-in validators.

import { NonNullableFormBuilder, Validators } from '@angular/forms';
import { inject } from '@angular/core';

export class LoginForm {
  private fb = inject(NonNullableFormBuilder);

  form = this.fb.group({
    email: ['', [Validators.required, Validators.email]],
    password: ['', [Validators.required, Validators.minLength(8)]]
  });

  onSubmit() {
    if (this.form.valid) {
      const rawData = this.form.getRawValue();
    }
  }
}

11. RxJS & Signals Interoperability

Bridging RxJS Streams and Signals.

import { toSignal, toObservable } from '@angular/core/rxjs-interop';
import { signal, inject } from '@angular/core';

// Convert Observable to Signal
usersSignal = toSignal(this.userService.getUsers(), { initialValue: [] });

// Convert Signal to Observable
searchTerm = signal('');
searchTerm$ = toObservable(this.searchTerm);

12. Projection & Query Signals

`viewChild`, `contentChild`, and multi-slot projection.

<!-- Modal Template -->
<div class="modal">
  <ng-content select="[header]" />
  <ng-content /> <!-- Default Body Slot -->
</div>

// TS Component Class Query Signals
header = viewChild<ElementRef>('header');
children = viewChildren(ChildComponent);
projected = contentChild(TemplateRef);

13. Lifecycle Hooks & Cleanups

Execution phases and functional cleanup hooks.

ngOnInit()          # Executed after input bindings setup
ngOnChanges(c)      # Executed when input properties change
ngAfterViewInit()   # Executed after view initialization
ngOnDestroy()       # Executed before component destruction

// Functional cleanup with DestroyRef
private destroyRef = inject(DestroyRef);
constructor() {
  const sub = stream$.subscribe();
  this.destroyRef.onDestroy(() => sub.unsubscribe());
}

14. State Management (Signal Store Pattern)

Reactive central state management with Signals.

import { Injectable, signal, computed } from '@angular/core';

export interface CartItem { id: string; price: number; quantity: number; }

@Injectable({ providedIn: 'root' })
export class CartStore {
  private itemsSignal = signal<CartItem[]>([]);

  readonly items = this.itemsSignal.asReadonly();
  readonly itemCount = computed(() => this.itemsSignal().reduce((acc, i) => acc + i.quantity, 0));
  readonly totalPrice = computed(() => this.itemsSignal().reduce((acc, i) => acc + i.price * i.quantity, 0));

  addItem(newItem: CartItem) {
    this.itemsSignal.update(items => {
      const existing = items.find(i => i.id === newItem.id);
      return existing
        ? items.map(i => i.id === newItem.id ? { ...i, quantity: i.quantity + 1 } : i)
        : [...items, newItem];
    });
  }

  removeItem(id: string) {
    this.itemsSignal.update(items => items.filter(i => i.id !== id));
  }
}

15. SSR & Event Hydration

Configure Client Hydration and Fetch API for server render.

import { bootstrapApplication, provideClientHydration, withEventReplay } from '@angular/platform-browser';
import { provideHttpClient, withFetch } from '@angular/common/http';

bootstrapApplication(AppComponent, {
  providers: [
    provideClientHydration(withEventReplay()),
    provideHttpClient(withFetch())
  ]
});

16. Security & DomSanitizer

XSS prevention and DOM sanitization.

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { inject } from '@angular/core';

export class SecureComponent {
  private sanitizer = inject(DomSanitizer);
  trustedHtml: SafeHtml = '';

  setUntrustedContent(rawHtml: string) {
    this.trustedHtml = this.sanitizer.sanitize(SecurityContext.HTML, rawHtml) || '';
  }
}

17. Unit Testing (`TestBed`)

Testing Standalone components and service mocks.

import { TestBed } from '@angular/core/testing';

beforeEach(async () => {
  await TestBed.configureTestingModule({
    imports: [UserProfileComponent],
    providers: [{ provide: UserService, useValue: spy }]
  }).compileComponents();
});

18. Legacy `NgModule` Structure

Module declarations for non-standalone codebases.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  declarations: [LegacyComponent],
  imports: [CommonModule],
  exports: [LegacyComponent]
})
export class LegacyModule {}

Complete end-to-end Angular cheat sheet covering CLI tooling, Standalone architecture, Signals, template control flow, routing, HTTP interceptors, forms, state management, SSR, security, and unit testing in a single file.