ngAfterViewChecked()

ngAfterViewChecked()

When it's called:

  • Runs after ngAfterViewInit() and after every change detection cycle involving the component's view and child views.

Use case:

  • For logic that must occur after the view has been rendered and checked.
  • Useful when:
  • Reacting to dynamic layout changes or view-related computations.
  • Interacting with elements that might change after updates.
  • Running animations or post-render updates.

Performance & Caution:

  • Since it runs after every view check, avoid:
  • Expensive operations inside it.
  • Making changes that trigger further change detection (can cause infinite loops).
  • Use ChangeDetectorRef or setTimeout() carefully if you must update the view.

 

Example 1: Simple DOM Dimension Check

import { Component, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';

@Component({

  selector: 'app-after-view-checked-example',

  template: `<div #myDiv>{{ message }}</div>`,

})

export class AfterViewCheckedExampleComponent implements AfterViewChecked {

  message = 'Initial message';

  @ViewChild('myDiv') myDivRef!: ElementRef;

 

  ngAfterViewChecked(): void {

    console.log('ngAfterViewChecked() called');

    if (this.myDivRef && this.myDivRef.nativeElement.offsetHeight > 50) {

      this.message = 'Div is now taller than 50px!';

    }

  }

}

Example 2: Watch Dynamic Height

 

@Component({

  selector: 'app-dimension-checker',

  template: `<div #resizable>This content can resize.</div>`,

})

export class DimensionCheckerComponent implements AfterViewChecked {

  @ViewChild('resizable') resizableDiv!: ElementRef;

  previousHeight: number | null = null;

 

  ngAfterViewChecked(): void {

    const currentHeight = this.resizableDiv.nativeElement.offsetHeight;

    if (this.previousHeight !== null && currentHeight !== this.previousHeight) {

      console.log('Div height changed to:', currentHeight);

    }

    this.previousHeight = currentHeight;

  }

}

Example 3: Interact with Child Component

import { Component, AfterViewChecked, ViewChild } from '@angular/core';

import { ChildComponent } from './child.component';

 

@Component({

  selector: 'app-parent',

  template: `<app-child></app-child>`,

})

export class ParentComponent implements AfterViewChecked {

  @ViewChild(ChildComponent) childComp!: ChildComponent;

 

  ngAfterViewChecked(): void {

    if (this.childComp && this.childComp.someState) {

      console.log('Child component state updated:', this.childComp.someState);

    }

  }

}

Best Practices Summary:

  • Import and implement AfterViewChecked.
  • Use conditions to avoid unnecessary logic execution.
  • Avoid changing bindings directly — use async strategies if needed.
  • Keep the logic light to avoid performance issues.

 

ngAfterViewChecked() — Repeated view check after every change detection cycle

import { Component, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';

 

@Component({

  selector: 'app-after-view-checked-example',

  template: `<div #myDiv>{{ message }}</div>`

})

export class AfterViewCheckedExampleComponent implements AfterViewChecked {

  message = 'Initial message';

 

  @ViewChild('myDiv') myDivRef!: ElementRef;

 

  ngAfterViewChecked(): void {

    console.log('ngAfterViewChecked() called');

    if (this.myDivRef && this.myDivRef.nativeElement.offsetHeight > 50) {

      this.message = 'Div is now taller than 50px!';

    }

  }

}

 

Best Practice: Avoid infinite loops in ngAfterViewChecked()

ngAfterViewChecked(): void {

  // BAD: This could trigger change detection again, causing an infinite loop

  // this.someProperty = 'updated';

 

  // GOOD: Use asynchronous update if needed

  setTimeout(() => {

    // safe update

  });

}

 

Use Case: Detect dimension changes

import { Component, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';

 

@Component({

  selector: 'app-dimension-checker',

  template: `<div #resizable>This content can resize.</div>`

})

export class DimensionCheckerComponent implements AfterViewChecked {

  @ViewChild('resizable') resizableDiv!: ElementRef;

  previousHeight: number | null = null;

 

  ngAfterViewChecked(): void {

    const currentHeight = this.resizableDiv.nativeElement.offsetHeight;

    if (this.previousHeight !== null && currentHeight !== this.previousHeight) {

      console.log('Div height changed to:', currentHeight);

    }

    this.previousHeight = currentHeight;

  }

}

 

Use Case: Read child component state

import { Component, AfterViewChecked, ViewChild } from '@angular/core';

import { ChildComponent } from './child.component';

 

@Component({

  selector: 'app-parent',

  template: `<app-child></app-child>`

})

export class ParentComponent implements AfterViewChecked {

  @ViewChild(ChildComponent) childComp!: ChildComponent;

 

  ngAfterViewChecked(): void {

    if (this.childComp && this.childComp.someState) {

      console.log('Child component state updated:', this.childComp.someState);

    }

  }

}

Comments

Popular posts from this blog

Promises in Angular

Mastering Your Angular Workflow: Essential CLI Commands for Efficient Development

Observables in Angular