ANGULAR: Angular Component Lifecycle

Every Angular component goes through a predictable sequence of lifecycle events from creation to destruction. Lifecycle hooks give you the ability to execute your own code at each stage, enabling precise control over initialization, change detection, and cleanup.

Every Angular component has a lifecycle defined by a series of events that occur throughout its existence. When an event occurs, you can execute your own code using lifecycle hooks — special methods that Angular calls at defined moments.

Some lifecycle hooks occur only once, while others occur multiple times as data changes throughout the life of the component.


The Lifecycle Hooks

Angular provides a set of lifecycle hooks that cover every phase of a component's life:

md
Component Created
       |
       v
  OnChanges (if inputs)
       |
       v
    OnInit
       |
       v
    DoCheck
       |
       v
 AfterContentInit
       |
       v
AfterContentChecked
       |
       v
  AfterViewInit
       |
       v
 AfterViewChecked
       |
       v
   (Repeat OnChanges -> DoCheck -> AfterContentChecked -> AfterViewChecked
    each time input data changes)
       |
       v
   OnDestroy
       |
       v
Component Destroyed


Hooks That Run Only Once

These hooks fire a single time during the component's lifetime:

HookWhen It Runs
OnInitAfter the first OnChanges, when the component is initialized
AfterContentInitAfter Angular projects content into the component's view
AfterViewInitAfter Angular initializes the component's views and child views
OnDestroyJust before Angular destroys the component

ngOnInit is by far the most commonly used lifecycle hook. It is the right place to fetch initial data from a service, because the component's inputs are fully set by the time it runs.

ngOnDestroy is the right place to clean up — unsubscribe from observables, cancel timers, and detach event listeners to prevent memory leaks.


Hooks That Run Multiple Times

These hooks fire on every change detection cycle, triggered whenever input data changes:

HookWhen It Runs
OnChangesBefore ngOnInit and whenever an input property changes
DoCheckDuring every change detection run
AfterContentCheckedAfter every check of the projected content
AfterViewCheckedAfter every check of the component's views and child views

ngOnChanges receives a SimpleChanges object that shows you the previous and current values of input properties, making it useful when you need to react specifically to input changes.


The Full Lifecycle Order

When inputs change, Angular runs the hooks in this order:

md
1. OnChanges          (only if input properties change)
2. OnInit             (only once, on first run)
3. DoCheck
4. AfterContentInit   (only once)
5. AfterContentChecked
6. AfterViewInit      (only once)
7. AfterViewChecked
8. OnDestroy          (only once, on destruction)


Implementing a Lifecycle Hook

Using a lifecycle hook is a two-step process.

Step 1 — Import the lifecycle interface

typescript
import { Component, OnInit } from '@angular/core';

Step 2 — Implement the interface in your component class

typescript
export class HomeComponent implements OnInit {

  constructor() {}

  ngOnInit(): void {
    // Code here runs once when the component initializes
    console.log('HomeComponent initialized');
  }
}

The implements OnInit declaration is optional in TypeScript but is a strong convention — it tells both the compiler and other developers that this component deliberately uses the hook.


Practical Example: Fetching Data on Init

The most common use of ngOnInit is fetching data from a service when the component first loads:

typescript
import { Component, OnInit } from '@angular/core';
import { ProductService } from './product.service';
import { IProduct } from './product.model';

export class CatalogComponent implements OnInit {
  products: IProduct[] = [];

  constructor(private productService: ProductService) {}

  ngOnInit(): void {
    this.products = this.productService.getProducts();
  }
}

This is preferred over fetching data in the constructor because Angular's dependency injection and input bindings are fully resolved by the time ngOnInit runs.


Practical Example: Cleanup on Destroy

typescript
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

export class DataComponent implements OnDestroy {
  private subscription: Subscription;

  constructor(private dataService: DataService) {
    this.subscription = this.dataService.data$.subscribe(data => {
      // handle data
    });
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe(); // prevent memory leaks
  }
}


Summary

Angular lifecycle hooks give you precise control over what happens at every stage of a component's existence. The key hooks to master first are:

  • ngOnInit — for initialization logic and data fetching
  • ngOnChanges — for reacting to input property changes
  • ngOnDestroy — for cleanup and preventing memory leaks

Understanding the lifecycle order is essential for writing correct, efficient Angular components.