Lifecycle Hooks
📚 What are Lifecycle Hooks?
Angular calls lifecycle hook methods at specific moments in a component's lifecycle:
- constructor: Called first, before any lifecycle hook
- ngOnChanges: Called when input properties change
- ngOnInit: Called once after first ngOnChanges
- ngDoCheck: Called during every change detection
- ngAfterContentInit: After content projection (ng-content)
- ngAfterContentChecked: After every content check
- ngAfterViewInit: After component's view initialized
- ngAfterViewChecked: After every view check
- ngOnDestroy: Before component is destroyed
🎯 Interview Questions
- Q1: What is the difference between ngOnInit and constructor?
- A: Constructor is for DI setup. ngOnInit is for initialization logic when inputs are ready.
- Q2: When should you use ngOnDestroy?
- A: For cleanup: unsubscribe from observables, remove event listeners, clear timers.
- Q3: What is DestroyRef? (Angular 16+)
- A: Injectable that allows registering cleanup callbacks, can be used outside component class.
- Q4: What is takeUntilDestroyed()? (Angular 16+)
- A: RxJS operator that auto-unsubscribes when component is destroyed. Cleaner than manual unsubscribe.
🔧 Live Demo - Lifecycle Events
Lifecycle Log (check console)
Open browser DevTools to see lifecycle hooks firing
📋 Lifecycle Order
1. constructor()
2. ngOnChanges() ← when inputs change
3. ngOnInit() ← initialization
4. ngDoCheck()
5. ngAfterContentInit() ← ng-content ready
6. ngAfterContentChecked()
7. ngAfterViewInit() ← view ready
8. ngAfterViewChecked()
9. ngOnDestroy() ← cleanup
💻 Code Example
import { Component, OnInit, OnDestroy, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { interval } from 'rxjs';
@Component({...})
export class MyComponent implements OnInit, OnDestroy {
private readonly destroyRef = inject(DestroyRef);
constructor() {
// Modern approach with takeUntilDestroyed (v16+)
interval(1000).pipe(
takeUntilDestroyed() // Auto-unsubscribes!
).subscribe(console.log);
}
ngOnInit(): void {
console.log('Component initialized, inputs ready');
// Register cleanup with DestroyRef (v16+)
this.destroyRef.onDestroy(() => {
console.log('Cleanup via DestroyRef');
});
}
ngOnDestroy(): void {
console.log('Component destroyed - cleanup here');
}
}