Angular provides a series of lifecycle hooks that enable developers to tap into different stages of a component’s lifecycle. These hooks offer opportunities to perform actions at specific moments, such as initialization, data changes, and component destruction. In this article, we’ll explore each of these hooks in detail, providing clear examples to illustrate their purpose and usage.
ngOnChanges: Responding to Input Changes
The ngOnChanges
hook is invoked when any of the component’s input properties change. This provides a chance to respond to these changes and take appropriate actions.
Example:
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent implements OnChanges {
@Input() data: string;
ngOnChanges(changes: SimpleChanges): void {
if (changes.data) {
this.message = `Data changed to: ${changes.data.currentValue}`;
}
}
}
ngOnInit: Initializing the Component
The ngOnInit
hook is called once, after the component has been initialized. It is commonly used for tasks like fetching initial data or setting up subscriptions.
Example:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent implements OnInit {
message: string;
ngOnInit(): void {
this.message = 'Component initialized!';
}
}
ngDoCheck: Detecting Changes Manually
The ngDoCheck
hook is invoked during every change detection run and can be used to implement custom change detection logic.
Example:
import { Component, DoCheck } from '@angular/core';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent implements DoCheck {
data: any;
prevData: any;
message: string;
ngDoCheck(): void {
if (this.data !== this.prevData) {
this.message = 'Data has changed!';
this.prevData = this.data;
}
}
}
ngAfterContentInit and ngAfterContentChecked: Working with Projected Content
These hooks are called after Angular projects external content into the component. ngAfterContentInit
is called once after the first ngDoCheck
, while ngAfterContentChecked
is called after every subsequent ngDoCheck
.
Example:
import { Component, AfterContentInit, AfterContentChecked } from '@angular/core';
@Component({
selector: 'app-example',
template: '<ng-content></ng-content>'
})
export class ExampleComponent implements AfterContentInit, AfterContentChecked {
ngAfterContentInit(): void {
console.log('Content initialized');
}
ngAfterContentChecked(): void {
console.log('Content checked');
}
}
ngAfterViewInit and ngAfterViewChecked: Working with Views
These hooks are called after the component’s views (and child views) have been initialized. ngAfterViewInit
is called once after the first ngAfterContentChecked
, while ngAfterViewChecked
is called after every subsequent ngAfterContentChecked
.
Example:
import { Component, AfterViewInit, AfterViewChecked } from '@angular/core';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent implements AfterViewInit, AfterViewChecked {
message: string;
ngAfterViewInit(): void {
this.message = 'View initialized!';
}
ngAfterViewChecked(): void {
console.log('View checked');
}
}
ngOnDestroy: Cleanup Before Component Destruction
The ngOnDestroy
hook is called just before the component is destroyed. It provides an opportunity to perform cleanup tasks such as unsubscribing from observables.
Example:
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent implements OnDestroy {
message: string;
private subscription: Subscription;
constructor() {
this.subscription = /* subscribe to an observable */;
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
this.message = 'Component destroyed!';
}
}
Understanding these Angular component lifecycle hooks empowers you to manage your component effectively, ensuring that tasks like initialization, cleanup, and responsiveness to changes are handled with precision. Each hook serves a specific purpose in the grand lifecycle of a component, offering you the flexibility to tailor your code to the needs of your application.