Change Detection Strategy in Angular
Tags: angular, angular7, changedetection, javascript
Published: 2020-02-06 12:32:24

---
title: Change Detection Strategy in Angular
published: true
description: 
tags: #angular #angular7 #ChangeDetection #javascript
---

**[Update]** https://netbasal.com/reduce-change-detection-cycles-with-event-coalescing-in-angular-c4037199859f

#Angular9 is released, and we have now even more improved change detection cycle with option setting in main.ts file 

```javascript
   platformBrowserDynamic()
  .bootstrapModule(AppModule, { ngZoneEventCoalescing: true })
  .catch(err => console.error(err));
```

In angular framework we need to detect changes whenever there is changes on model side of your component happen. This has to reflect to update component view [DOM-UPDATE] automatically. So doing this work angular provides us zone.js, and handles every angular change detection cycle out of the box.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0aoiod1u67r0cmjvug95.jpg)

Angular runs change detection for every component try every time model has changed. This would cause more performance issue when you have plenty number of component tree in your angular app and you only update model of one component of tree, by default angular runs change detection for all of the available component tree and this is big performance issue. [ Later on we see how to update this default strategy ].

One major common error behavior you as a developer see while changing component model to frequently is "**ExpresionChangedAfterItHasBeenCheckedError**". So, What does this error tells us is simply that, angular is in ChangeDetection cycle and after just in between some model values are changed and its quite confusing to know which value to update to view. [There are ways to fix this problem too].

Angular uses zone.js and takes all component reference as a tree data structures.  So, theres must to have one parenet component and others are their child component. 

In below code example you can get **"ExpresionHasChangedAfterItHasBeenCheckedError**". Because of first We are initializing `checkboxes` object and in `ngAfterViewInit()` life cycle hook we attempt to change objects check property to false. Thus angular gives error because of ChangeDetection has found that something has changed before finishing updating DOM cycle and that is ambiguity. Simply, This error is coming because existing value is getting updated immediately after getting initialized.

```javascript
export class AppComponent  {
  name = 'Angular';
  checkboxes = [{
      label : 'Sunday',
      checked : true
  },{
      label : 'Monday',
      checked : false
  },{
      label : 'Tuesday',
      checked : false
  },{
      label : 'Wednesday',
      checked : true
  },{
      label : 'Thursday',
      checked : false
  },{
      label : 'Friday',
      checked : true
  },{
      label : 'Saturday',
      checked : true
  }];
  ngOnInit(){
  }
  ngAfterViewInit(){
    this.changeStatus() // This line cause ExpresionChangedError
  }
  changeStatus(){
    this.checkboxes.map(item => item.checked === false ? item.checked=true : item.checked=false);
  }
 }
}
```

**Solutions to Above Problem**

1. Very First and dirty and quick solution is to use `setTimeOut()` async method.
       
     Change this code in `ngAfterViewInit()` to this...

     ```javascript
        ngAfterViewInit(){  
           setTimeout(()=> {
             this.changeStatus()
           })  
        }
     ```
     By applying above changes `setTimeOut()` will call angular change detection cycle for us automatically.   

2. By using `ChangeDetectorRef` and injecting using dependency into the constructor of the component.This is angular way of doing changeDetection using `detectChanges()` method of `ChangeDetectorRef`. we tell angular explicitly to detect change of DOM because of We have changed model. 

     ```javascript
          constructor(private  cdr : ChangeDetectorRef){}
          ngAfterViewInit(){  
             this.changeStatus();
             this.cdr.detectChanges();  
          }
     ```