What are Lifecycle Hooks?
Angular lifecycle hooks are special methods that Angular calls automatically at different stages of a component's or directive's lifecycle.
A component goes through several stages:
Component Created
↓
Inputs Initialized
↓
Component Initialized
↓
View Created
↓
Changes Detected
↓
Component Used
↓
Component Destroyed
Angular provides lifecycle hooks so that we can execute our own code at these specific stages.
For example:
ngOnInit()
runs after Angular initializes the component.
ngOnDestroy()
runs just before Angular destroys the component.
Why do we need Lifecycle Hooks?
Sometimes code must execute at a specific point in the component lifecycle.
For example:
- Load data when a component initializes.
- Respond when an
@Input()value changes. - Access child elements after the view is initialized.
- Perform logic after content projection.
- Clean up timers, subscriptions, or other resources when a component is destroyed.
Without lifecycle hooks, we would not have a structured way to execute logic at these stages.
Important Angular Lifecycle Hooks
The traditional lifecycle hooks commonly discussed in interviews are:
| Hook | Purpose |
|---|---|
ngOnChanges() |
Runs when input values change |
ngOnInit() |
Runs once after initialization |
ngDoCheck() |
Runs during change-detection checks |
ngAfterContentInit() |
Runs after projected content initializes |
ngAfterContentChecked() |
Runs after projected content is checked |
ngAfterViewInit() |
Runs after component view initializes |
ngAfterViewChecked() |
Runs after component view is checked |
ngOnDestroy() |
Runs before component destruction |
Modern Angular also provides render callbacks such as afterNextRender() and afterEveryRender(), but the hooks above remain fundamental lifecycle concepts.
Lifecycle Hook Order
A useful simplified sequence is:
Constructor
↓
ngOnChanges()
↓
ngOnInit()
↓
ngDoCheck()
↓
ngAfterContentInit()
↓
ngAfterContentChecked()
↓
ngAfterViewInit()
↓
ngAfterViewChecked()
↓
Component running
↓
ngOnDestroy()
During later change-detection cycles, hooks such as:
ngOnChanges() ← if inputs changed
ngDoCheck()
ngAfterContentChecked()
ngAfterViewChecked()
can execute again.
Full Simple Sample Program
app.ts
import {
Component,
OnInit,
OnDestroy,
DoCheck,
AfterViewInit
} from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<h2>Angular Lifecycle Hooks</h2>
<p>{{ message }}</p>
`
})
export class App
implements OnInit, DoCheck, AfterViewInit, OnDestroy {
message = 'Hello Angular';
constructor() {
console.log('1. Constructor called');
}
ngOnInit(): void {
console.log('2. ngOnInit called');
}
ngDoCheck(): void {
console.log('3. ngDoCheck called');
}
ngAfterViewInit(): void {
console.log('4. ngAfterViewInit called');
}
ngOnDestroy(): void {
console.log('5. ngOnDestroy called');
}
}
Program Explanation
1. Constructor
constructor() {
console.log('1. Constructor called');
}
The constructor is a TypeScript/JavaScript class constructor, not an Angular lifecycle hook.
It runs when Angular creates the class instance.
It is commonly used for dependency injection:
constructor(private productService: ProductService) {
}
Avoid putting substantial initialization logic in the constructor.
2. ngOnInit()
ngOnInit(): void {
console.log('2. ngOnInit called');
}
ngOnInit() runs once after Angular has initialized the component's input values.
It is one of the most commonly used hooks.
Typical uses:
Load initial data
Initialize component state
Call a service
Perform startup logic
For example:
ngOnInit(): void {
this.loadProducts();
}
3. ngDoCheck()
ngDoCheck(): void {
console.log('3. ngDoCheck called');
}
ngDoCheck() runs when Angular checks the component for changes.
It allows custom change-detection logic.
Important
It can run very frequently, so expensive operations should not be placed inside it.
4. ngAfterViewInit()
ngAfterViewInit(): void {
console.log('4. ngAfterViewInit called');
}
This runs once after Angular initializes the component's view and child views.
It is particularly useful when working with view queries such as:
@ViewChild(...)
Example:
@ViewChild('myInput')
input!: ElementRef;
ngAfterViewInit() {
this.input.nativeElement.focus();
}
At this point, the view has been created, so the queried element is available.
5. ngOnDestroy()
ngOnDestroy(): void {
console.log('5. ngOnDestroy called');
}
This runs immediately before Angular destroys the component.
It is used for cleanup.
Examples include:
Clear timers
Remove event listeners
Clean up subscriptions/resources
Close custom connections
For example:
ngOnDestroy(): void {
clearInterval(this.timer);
}
Understanding Every Hook
ngOnChanges()
Runs when Angular sets or changes input properties.
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
}
For example:
@Input() productId!: number;
If the parent changes productId, Angular can call:
ngOnChanges()
It can run multiple times.
ngOnInit()
Runs once during initialization.
ngOnInit() {
this.loadProducts();
}
Most commonly used for initial component setup.
ngDoCheck()
Runs during change-detection checks.
ngDoCheck() {
console.log('Checking changes');
}
Use carefully because it can execute frequently.
ngAfterContentInit()
Runs once after Angular initializes content projected using:
<ng-content></ng-content>
Example:
ngAfterContentInit() {
console.log('Projected content initialized');
}
ngAfterContentChecked()
Runs after Angular checks projected content.
ngAfterContentChecked() {
console.log('Projected content checked');
}
It can execute multiple times.
ngAfterViewInit()
Runs once after the component's view and child views are initialized.
ngAfterViewInit() {
console.log('View initialized');
}
Frequently associated with:
ViewChild
ViewChildren
DOM/view-related initialization
ngAfterViewChecked()
Runs after Angular checks the component's view and child views.
ngAfterViewChecked() {
console.log('View checked');
}
It can execute frequently, so avoid expensive operations here.
ngOnDestroy()
Runs before Angular destroys the component.
ngOnDestroy() {
console.log('Component destroyed');
}
Used primarily for cleanup.
Advantages
1. Proper initialization
You can initialize data at the correct stage.
ngOnInit() {
this.loadData();
}
2. Detect input changes
ngOnChanges()
allows a component to respond when its inputs change.
3. Access initialized views
ngAfterViewInit()
allows view-dependent operations after the view exists.
4. Resource cleanup
ngOnDestroy()
provides a clear place for cleanup logic.
5. Predictable component behavior
Lifecycle hooks give developers well-defined execution points.
Disadvantages / Things to Be Careful About
Lifecycle hooks themselves are not a disadvantage, but incorrect usage can create problems.
1. Some hooks run frequently
For example:
ngDoCheck()
ngAfterContentChecked()
ngAfterViewChecked()
Heavy logic inside them can affect performance.
2. Wrong hook can cause timing problems
For example, attempting to access a view query too early can fail because the view may not yet be initialized.
3. Too much lifecycle logic reduces maintainability
A component containing complex logic across every lifecycle hook can become difficult to understand.
Most Important Hooks for Interviews
You should particularly understand these:
ngOnChanges()
↓
Input changed
ngOnInit()
↓
Initialize component
ngAfterViewInit()
↓
View ready
ngOnDestroy()
↓
Cleanup
These are encountered frequently in practical Angular development.
Key Points
- Lifecycle hooks are methods Angular invokes automatically at specific component/directive lifecycle stages.
constructoris not an Angular lifecycle hook.ngOnChanges()responds to input changes.ngOnInit()runs once during initialization.ngDoCheck()supports custom change checking.ngAfterContentInit()relates to projected content.ngAfterViewInit()runs after the component view is initialized.ngOnDestroy()is used for cleanup.- Some hooks run only once, while others can run repeatedly.
- Avoid expensive operations inside frequently executed hooks.
Interview Questions and Answers
1. What are Angular lifecycle hooks?
Lifecycle hooks are methods that Angular automatically invokes at specific stages of a component or directive's lifecycle, such as initialization, change checking, view initialization, and destruction.
2. Is the constructor a lifecycle hook?
No.
The constructor is a JavaScript/TypeScript class feature. Angular lifecycle hooks include methods such as ngOnInit() and ngOnDestroy().
3. What is the difference between constructor and ngOnInit()?
The constructor executes when the class instance is created and is commonly used for dependency injection.
ngOnInit() is an Angular lifecycle hook that runs after Angular initializes the component and its initial inputs.
4. Which lifecycle hook is commonly used to load initial data?
ngOnInit()
Example:
ngOnInit() {
this.loadProducts();
}
5. Which hook detects changes to input properties?
ngOnChanges()
It receives a SimpleChanges object describing input changes.
6. Which hook is commonly associated with ViewChild?
ngAfterViewInit()
It executes after the component's view has been initialized.
7. Which hook is used for cleanup?
ngOnDestroy()
It is used to clean up resources when the component is being destroyed.
8. Which hooks should be used carefully because they can run frequently?
Especially:
ngDoCheck()
ngAfterContentChecked()
ngAfterViewChecked()
Heavy processing in these hooks can negatively affect performance.
Easy way to remember
OnChanges → Input changed
OnInit → Component initialized
DoCheck → Check changes
AfterContent → Projected content
AfterView → Component view
OnDestroy → Cleanup
For interviews, the most important mental model is: Angular creates the component → initializes inputs/state → initializes content/view → repeatedly checks for changes → destroys the component.