← Back to Articles         
What is ngDoCheck() in Angular?

What is ngDoCheck() in Angular?

Published on 30 Sep 2026     6 min read Angular
Component Lifecycle

ngDoCheck() is an Angular lifecycle hook that allows a component or directive to perform custom change detection.

Angular calls ngDoCheck() whenever it runs change detection for that component.

ngDoCheck(): void {
  // Custom change-detection logic
}

It comes from Angular's DoCheck lifecycle interface:

import { DoCheck } from '@angular/core';

Simple definition: ngDoCheck() lets us manually check for changes that Angular's normal lifecycle mechanisms may not directly expose in the way we need.


Why do we need ngDoCheck()?

Normally, Angular automatically detects changes and updates the UI.

For example:

name = 'Syed';

If name changes:

this.name = 'Mohamed';

Angular updates the view automatically.

So, most applications do not need ngDoCheck().

It becomes useful when we need custom logic during Angular's change-detection cycle, especially when monitoring changes that aren't conveniently handled by ngOnChanges().

For example, suppose a component has an object:

user = {
  name: 'Syed',
  city: 'Erode'
};

Later, only a property is modified:

this.user.name = 'Mohamed';

The object reference remains the same.

If this object were passed to a child through @Input(), ngOnChanges() is primarily associated with changes to the input binding value/reference. ngDoCheck() can be used when you need your own checking logic for such internal mutations.


Full Simple Sample Program

Let's create a parent component that passes a user object to a child.

app.ts — Parent

import { Component } from '@angular/core';
import { UserComponent } from './user';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [UserComponent],
  template: `
    <h2>Parent Component</h2>

    <button (click)="changeName()">
      Change Name
    </button>

    <app-user [user]="user"></app-user>
  `
})
export class App {

  user = {
    name: 'Syed',
    city: 'Erode'
  };

  changeName() {
    this.user.name = 'Mohamed';
  }
}

user.ts — Child

import {
  Component,
  DoCheck,
  Input
} from '@angular/core';

@Component({
  selector: 'app-user',
  standalone: true,
  template: `
    <h2>Child Component</h2>

    <p>Name: {{ user.name }}</p>
    <p>City: {{ user.city }}</p>
  `
})
export class UserComponent implements DoCheck {

  @Input() user!: {
    name: string;
    city: string;
  };

  previousName = '';

  ngDoCheck(): void {

    if (this.user.name !== this.previousName) {

      console.log(
        'Name changed:',
        this.previousName,
        '->',
        this.user.name
      );

      this.previousName = this.user.name;
    }
  }
}

Explanation

Initially:

user = {
  name: 'Syed',
  city: 'Erode'
};

The parent sends the object to the child:

<app-user [user]="user"></app-user>

The child receives it:

@Input() user!: {
  name: string;
  city: string;
};

When we click:

<button (click)="changeName()">

this executes:

this.user.name = 'Mohamed';

Notice that we are not creating a new object.

We are modifying a property of the existing object.

Conceptually:

Before

user ──────► Object A
             name = Syed


After

user ──────► Object A
             name = Mohamed

The reference is still:

Object A

Our ngDoCheck() performs a custom comparison:

if (this.user.name !== this.previousName)

If the name changed:

console.log(...);

and then stores the latest value:

this.previousName = this.user.name;

ngOnChanges() vs ngDoCheck()

This is an important interview distinction.

ngOnChanges() ngDoCheck()
Designed to react to @Input() binding changes Used for custom change-detection logic
Receives SimpleChanges Does not receive SimpleChanges
Convenient for changed input values/references Can manually inspect object properties/collections
Called when Angular detects input changes Called during change-detection checks
Usually preferred when sufficient Use only when custom checking is necessary

For example:

this.user = {
  name: 'Mohamed',
  city: 'Erode'
};

Here we created a new object reference, which is straightforward for ngOnChanges() to observe as an input change.

But:

this.user.name = 'Mohamed';

mutates the existing object. If you specifically need lifecycle logic for that internal mutation, ngDoCheck() can perform your own comparison.


Advantages

1. Custom change detection

You have control over what should be checked.

if (this.user.name !== this.previousName)

2. Useful for complex objects

It can help detect specific internal mutations in:

Object
Array
Collection

3. More control

You can implement application-specific checking logic that isn't naturally expressed through ngOnChanges().


Disadvantages

The biggest disadvantage is performance.

ngDoCheck() can run very frequently because Angular invokes it during change-detection cycles.

For example:

ngDoCheck() {
  console.log('Checking...');
}

You may see this logged many times.

Therefore, avoid expensive operations such as:

ngDoCheck() {
  // Avoid expensive work here
  this.loadHugeData();
  this.callApi();
  this.performComplexCalculation();
}

In particular, do not call APIs from ngDoCheck() just because a value might have changed. It can cause repeated requests.


When should we use ngDoCheck()?

Use it when:

  • You genuinely need custom change detection
  • You need to inspect specific internal changes to objects or collections
  • ngOnChanges() does not provide the behavior you need

Avoid it when normal Angular mechanisms are enough.

In modern Angular, you should generally first consider normal bindings, immutable updates, signals, computed values, effects, or other appropriate reactive patterns before implementing manual checking in ngDoCheck().


Lifecycle Position

A simplified lifecycle sequence is:

Component Created
      ↓
ngOnChanges()
      ↓
ngOnInit()
      ↓
ngDoCheck()
      ↓
ngAfterContentInit()
      ↓
ngAfterContentChecked()
      ↓
ngAfterViewInit()
      ↓
ngAfterViewChecked()

During later change-detection cycles:

Change Detection
      ↓
ngDoCheck()
      ↓
Content Checked
      ↓
View Checked

So ngDoCheck() is not called only once.

It can execute repeatedly.


Key Points

  • ngDoCheck() is an Angular lifecycle hook.
  • It is used for custom change-detection logic.
  • It is called during Angular's change-detection checks.
  • It can be useful for detecting specific internal mutations in objects or arrays.
  • Unlike ngOnChanges(), it does not receive SimpleChanges.
  • It can run very frequently.
  • Keep the code inside ngDoCheck() lightweight.
  • Avoid API calls or expensive calculations inside it.
  • Use it only when Angular's normal/reactive mechanisms aren't sufficient.

Interview Questions and Answers

1. What is ngDoCheck()?

ngDoCheck() is an Angular lifecycle hook used to implement custom change-detection logic. Angular calls it during change-detection checks for the component or directive.

2. Why do we use ngDoCheck()?

We use it when we need to manually inspect changes that aren't conveniently handled through standard input-change handling such as ngOnChanges().

3. What is the difference between ngOnChanges() and ngDoCheck()?

ngOnChanges() reacts to changes in input bindings and provides SimpleChanges. ngDoCheck() runs during change detection and allows us to implement our own checking logic.

4. Is ngDoCheck() called only once?

No. It can be called many times throughout the component's lifetime as Angular performs change detection.

5. Can we call an API inside ngDoCheck()?

Technically possible, but it is generally a bad practice because ngDoCheck() can execute frequently and could trigger repeated API requests.

6. Does every Angular component need ngDoCheck()?

No. Most components do not need it. Angular's normal change detection and modern reactive APIs handle most scenarios.

Interview one-line answer

ngDoCheck() is an Angular lifecycle hook that runs during change detection and allows developers to implement custom logic for detecting changes that require manual inspection.

← Back to Articles