🔧 Dev Tools Dashboard

Angular • TypeScript • Performance

Angular
TypeScript
RxJS
Performance
Feb 2026

Component Lifecycle & Dependency Injection

Modern Angular 19+ patterns

lifecycle inject modern
import { inject } from '@angular/core';

// ✅ Modern: inject() function (no constructor needed!)
private service = inject(MyService);
private router = inject(Router);

// ngOnInit - initialization logic
ngOnInit(): void {
  this.loadData();
}

// ngOnChanges - react to input changes (rarely needed with signals!)
ngOnChanges(changes: SimpleChanges): void {
  if (changes['data']?.currentValue) {
    this.processData();
  }
}

// ngOnDestroy - cleanup subscriptions
ngOnDestroy(): void {
  this.subscription.unsubscribe();
}
Feb 2026

Signals (Angular 16+)

Modern reactive state management

signals reactive
import { signal, computed, effect } from '@angular/core';

// Writable signal
count = signal(0);

// Computed signal
doubled = computed(() => this.count() * 2);

// Effect - runs on signal changes
constructor() {
  effect(() => {
    console.log('Count changed:', this.count());
  });
}

// Update signal
increment() {
  this.count.update(v => v + 1);
  // or: this.count.set(5);
}
Feb 2026

Modern Control Flow (@if, @for)

Angular 17+ built-in control flow (no CommonModule!)

control-flow modern angular-17
// ✅ Modern @if (no *ngIf)
@if (user()) {
  <div>Welcome {{ user().name }}</div>
} @else {
  <div>Please log in</div>
}

// ✅ Modern @for (no *ngFor, built-in trackBy!)
@for (item of items(); track item.id) {
  <div>{{ item.name }}</div>
} @empty {
  <div>No items found</div>
}

// ✅ Modern @switch
@switch (status()) {
  @case ('loading') { <spinner /> }
  @case ('error') { <error-msg /> }
  @case ('success') { <data-view /> }
  @default { <div>Unknown</div> }
}
Feb 2026

Modern Inputs & Outputs (Signal-based)

Angular 17.1+ signal inputs/outputs

inputs outputs signals
import { Component, input, output } from '@angular/core';

@Component({
  selector: 'app-user-card',
  standalone: true,
  template: `
    <div>{{ user().name }}</div>
    <button (click)="handleClick()">Select</button>
  `
})
export class UserCardComponent {
  // ✅ Modern: signal-based input
  user = input.required<User>();
  
  // Optional with default
  theme = input('dark');
  
  // ✅ Modern: output (replaces EventEmitter)
  userSelected = output<User>();
  
  handleClick() {
    this.userSelected.emit(this.user());
  }
}
Feb 2026

Standalone Components

No NgModules needed (default in Angular 19)

standalone modern
import { Component, inject } from '@angular/core';

@Component({
  selector: 'app-my-component',
  standalone: true,  // Default in new projects!
  template: `
    @if (data()) {
      <h1>{{ data().title }}</h1>
    }
  `
})
export class MyComponent {
  private service = inject(DataService);
  data = this.service.getData();
}
Feb 2026

OnPush Change Detection

Optimize performance with OnPush strategy

performance change-detection
import { ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-optimized',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `...`
})
export class OptimizedComponent {
  // Only checks when:
  // - Input changes (reference)
  // - Event fires from template
  // - Observable emits (async pipe)
  // - Manual: cdr.markForCheck()
}
Feb 2026

Utility Types

Built-in TypeScript helpers

types utilities
interface User {
  id: number;
  name: string;
  email: string;
}

// Partial - all props optional
type PartialUser = Partial;

// Required - all props required
type RequiredUser = Required;

// Pick - select specific props
type UserPreview = Pick;

// Omit - exclude props
type UserWithoutEmail = Omit;

// Record - key-value map
type UserMap = Record;
Feb 2026

Type Guards

Runtime type checking

type-guards safety
// Simple type guard
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

// Object type guard
interface Cat { meow(): void; }
interface Dog { bark(): void; }

function isCat(animal: Cat | Dog): animal is Cat {
  return 'meow' in animal;
}

// Usage
if (isCat(myPet)) {
  myPet.meow(); // TypeScript knows it's a Cat
}
Feb 2026

Generics Patterns

Reusable type-safe code

generics patterns
// Generic function
function firstElement(arr: T[]): T | undefined {
  return arr[0];
}

// Generic class
class DataStore {
  private data: T[] = [];
  
  add(item: T): void {
    this.data.push(item);
  }
  
  get(index: number): T | undefined {
    return this.data[index];
  }
}

// Generic constraints
function getProperty(obj: T, key: K): T[K] {
  return obj[key];
}
Feb 2026

Common Operators

Most-used RxJS operators

rxjs operators
import { map, filter, switchMap, debounceTime, 
         distinctUntilChanged, takeUntil } from 'rxjs/operators';

// Transform values
data$.pipe(map(x => x * 2));

// Filter values
data$.pipe(filter(x => x > 10));

// Switch to new observable (cancel previous)
search$.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(term => this.api.search(term))
);

// Auto-unsubscribe pattern
private destroy$ = new Subject();

ngOnInit() {
  data$.pipe(
    takeUntil(this.destroy$)
  ).subscribe();
}

ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
Feb 2026

Subject Types

Different Subject behaviors

subjects multicasting
import { Subject, BehaviorSubject, ReplaySubject, AsyncSubject } from 'rxjs';

// Subject - no initial value, no replay
const subject = new Subject();

// BehaviorSubject - has initial value, replays last
const behavior = new BehaviorSubject(0);

// ReplaySubject - replays N previous values
const replay = new ReplaySubject(3);

// AsyncSubject - emits only last value on complete
const async = new AsyncSubject();
Feb 2026

Lazy Loading Modules

Load features on-demand

lazy-loading routing
// app-routing.module.ts
const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module')
      .then(m => m.AdminModule)
  },
  {
    path: 'dashboard',
    loadComponent: () => import('./dashboard/dashboard.component')
      .then(m => m.DashboardComponent) // Standalone
  }
];
Feb 2026

TrackBy Function

Optimize *ngFor rendering

ngFor optimization
// Template
{{ item.name }}
// Component trackByFn(index: number, item: any): any { return item.id; // unique identifier } // Without trackBy: Angular re-renders entire list // With trackBy: Angular only re-renders changed items
Feb 2026

Bundle Size Optimization

Reduce production bundle

build bundle-size
// angular.json - production config
"optimization": true,
"buildOptimizer": true,
"aot": true,
"sourceMap": false,

// Tree-shakeable providers
@Injectable({ providedIn: 'root' })

// Analyze bundle
ng build --stats-json
npx webpack-bundle-analyzer dist/*/stats.json

// Dynamic imports
const module = await import('./heavy-module');

// Remove unused code
// Use barrel imports carefully
// Lazy load routes
// Use OnPush change detection