In Angular, components go through a series of stages from their creation to destruction. These stages are collectively known as the Angular lifecycle. Understanding the lifecycle hooks provided by Angular allows developers to tap into key moments in a component's lifecycle to perform initialization, cleanup, and other crucial operations. This article provides an in-depth look at each of these lifecycle hooks and how to use them effectively.
Angular Lifecycle Hooks
Here is a list of the primary lifecycle hooks in Angular.
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnDestroy
Let's explore each of these hooks in detail.
1. ngOnChanges
- When it’s called: This hook is called whenever an input property bound to a component changes. It’s called before ngOnInit and whenever the input properties are updated.
- Use case: Use ngOnChanges to act on changes to input properties from the parent component.
Example
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-child',
template: '<p>{{data}}</p>',
})
export class ChildComponent implements OnChanges {
@Input() data: string;
ngOnChanges(changes: SimpleChanges) {
console.log('ngOnChanges called', changes);
}
}
2. ngOnInit
- When it’s called: This hook is called once, after the first ngOnChanges. It’s typically used for component initialization.
- Use case: Use ngOnInit to perform component initialization, like fetching data.
Example
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-example',
template: '<p>Example works!</p>',
})
export class ExampleComponent implements OnInit {
ngOnInit() {
console.log('ngOnInit called');
}
}
3. ngDoCheck
- When it’s called: This hook is called during every change detection run. It’s useful for custom change detection.
- Use case: Use ngDoCheck to implement custom change detection logic.
Example
import { Component, DoCheck } from '@angular/core';
@Component({
selector: 'app-check',
template: '<p>Check works!</p>',
})
export class CheckComponent implements DoCheck {
ngDoCheck() {
console.log('ngDoCheck called');
}
}
4. ngAfterContentInit
- When it’s called: This hook is called after Angular projects external content into the component’s view (ng-content).
- Use case: Use ngAfterContentInit to respond to content projection into the component.
Example
import { Component, AfterContentInit } from '@angular/core';
@Component({
selector: 'app-content',
template: '<ng-content></ng-content>',
})
export class ContentComponent implements AfterContentInit {
ngAfterContentInit() {
console.log('ngAfterContentInit called');
}
}
5. ngAfterContentChecked
- When it’s called: This hook is called after every check of the component’s projected content.
- Use case: Use ngAfterContentChecked to act after the content is checked.
Example
import { Component, AfterContentChecked } from '@angular/core';
@Component({
selector: 'app-content-check',
template: '<ng-content></ng-content>',
})
export class ContentCheckComponent implements AfterContentChecked {
ngAfterContentChecked() {
console.log('ngAfterContentChecked called');
}
}
6. ngAfterViewInit
- When it’s called: This hook is called after Angular initializes the component’s views and child views.
- Use case: Use ngAfterViewInit to perform actions after the component’s view is initialized.
Example
import { Component, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-view-init',
template: '<p>View Init works!</p>',
})
export class ViewInitComponent implements AfterViewInit {
ngAfterViewInit() {
console.log('ngAfterViewInit called');
}
}
7. ngAfterViewChecked
- When it’s called: This hook is called after every check of the component’s view.
- Use case: Use ngAfterViewChecked to act after the component’s view is checked.
Example
import { Component, AfterViewChecked } from '@angular/core';
@Component({
selector: 'app-view-check',
template: '<p>View Check works!</p>',
})
export class ViewCheckComponent implements AfterViewChecked {
ngAfterViewChecked() {
console.log('ngAfterViewChecked called');
}
}
8. ngOnDestroy
- When it’s called: This hook is called just before Angular destroys the component.
- Use case: Use ngOnDestroy for cleanup, like unsubscribing from observables and detaching event handlers.
Example
import { Component, OnDestroy } from '@angular/core';
@Component({
selector: 'app-destroy',
template: '<p>Destroy works!</p>',
})
export class DestroyComponent implements OnDestroy {
ngOnDestroy() {
console.log('ngOnDestroy called');
}
}
Lifecycle Sequence
Understanding the order of these hooks is crucial for correctly implementing logic that depends on the component's lifecycle stages.
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnDestroy
Practical Use Cases
- ngOnInit: Ideal for initialization tasks like fetching data from a service.
- ngOnChanges: Useful for reacting to changes in input properties.
- ngOnDestroy: Perfect for cleaning up resources, like unsubscribing from observables.
- ngAfterViewInit: Great for manipulating the DOM after the view is initialized.
Conclusion
Mastering Angular lifecycle hooks is essential for building robust and maintainable Angular applications. By understanding when and how to use each hook, developers can ensure their components are properly initialized, updated, and cleaned up. This not only leads to better performance but also improves code organization and readability.