Understanding Angular Change Detection for Beginners | Angular 17 Change Detection Methods

Follow on LinkedIn

Understanding how the Angular change detection technique helps in the process of building dynamic and responsive web applications. In this article, we’ll explore some essential concepts of Angular change detection with simple code examples.

Angular Change Detection

1. Detecting Change to @Input Binding

1.1 Using a Custom Setter

In Angular, components often communicate through properties. Imagine a parent component with a counter and a child component that displays this counter. We want the child to know when the counter changes. Let’s use a custom setter for this:

@Component({
  selector: 'app-child',
  template: `<p>{{counter}}</p>`
})
export class ChildComponent {
  _counter = 0;

  @Input() 
  set counter(newValue: number) {
    console.log("Counter updated:", newValue);
    this._counter = newValue;
  }

  get counter() {
    return this._counter;
  }
}

Explanation:

The child component has a counter property marked with @Input(), allowing it to receive updates from the parent.

Instead of directly updating counter, we use a special function called a custom setter (set counter(newValue: number)) to log the update and store the value in an internal variable _counter.

The get counter() method is a getter that returns the stored value.

1.2 Using ngOnChanges

Another way to handle changes is by using ngOnChanges. This method is called whenever the parent updates the counter property:

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

@Component({...})
export class ChildComponent implements OnChanges {
  @Input() counter = 0;

  ngOnChanges(changes: { [key: string]: SimpleChange }) {
    let c = changes;
    console.log("Previous Value:", c.previousValue, "Current Value:", c.currentValue);
  }
}

Explanation:

The ChildComponent implements the OnChanges interface and has a method called ngOnChanges.

Whenever the parent changes the counter , this method is called automatically.

Inside ngOnChanges, we can access the previous and current values of the counter.

2. Example Child and Parent Components

Now, let’s see a practical example with a parent and a child component:

@Component({
  selector: 'app-child',
  template: `<p>{{counter}}</p>`
})
export class ChildComponent {
  @Input() counter = 0;
}

@Component({
  selector: 'app-parent',
  template: `<app-child [counter]="p_counter"></app-child>
  <button (click)="update()">Update</button>`
})
export class ParentComponent {
  p_counter = 0;

  update() { this.p_counter += 1; }
}

Explanation:

The ChildComponent has a property counter marked with @Input(), allowing it to receive input from the parent.

The ParentComponent template uses <app-child [counter]="p_counter"></app-child> to pass the value of p_counter to the child’s counter.

When the button is clicked, the update() the method in the parent increments p_counter, triggering a change in the child.

3. Advanced Inter Component Communication

3.1 Direct Access to Child

3.1.1 Using a Template Local Variable

Sometimes, you need the parent to directly interact with the child without using @Input or @Output. Here’s a simple way to use a template local variable:

@Component({
  selector: 'app-parent',
  template: `
    <app-child #ch></app-child>
    <button (click)="ch.counter = ch.counter + 1">
      Update</button>
  `
})
export class ParentComponent {
}

Explanation:

In the parent’s template, #ch is a local variable representing an instance of ChildComponent.

The button click handler directly updates the counter property of the child using this local variable.

3.1.2 Using the @ViewChild Decorator

Alternatively, we can use @ViewChild decorator for direct access:

import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from '../child/child.component';

@Component({
  selector: 'app-parent',
  template: `<app-child></app-child>
  <button (click)="update()">Update</button>`
})
export class ParentComponent {
  @ViewChild(ChildComponent, { static: false }) child: ChildComponent;

  update() { this.child.counter += 1; }
}

Explanation:

The @ViewChild decorator in the parent component allows us to access an instance of ChildComponent.

{ static: false } means that the child component is not static and could change during the component’s lifecycle.

The update() method can now directly manipulate the properties or invoke methods of the child component.

Conclusion

In conclusion, these simple examples demonstrate the basics of Angular change detection. By understanding how @Input, custom setters, ngOnChanges, and direct component access work, you’re well on your way to mastering Angular component communication. As you delve deeper into Angular development, these concepts will become essential for building dynamic and efficient web applications. Happy Coding 🙂

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

×