Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression has changed after it was checked. Previous value: 'ng-valid: true'. Current value: 'ng-valid: false'

I have angular reactive form in parent component and sections inside childrens component.

Inside the child component I have a checkbox - when its checked - more fields open and I want them all to be required.

I am using setValidators but I'm getting error

ParentFormComponent.html:3 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ng-valid: true'. Current value: 'ng-valid: false'. at viewDebugError (core.js:7601) at expressionChangedAfterItHasBeenCheckedError (core.js:7589) at checkBindingNoChanges (core.js:7691) at checkNoChangesNodeInline (core.js:10560) at checkNoChangesNode (core.js:10541) at debugCheckNoChangesNode (core.js:11144) at debugCheckRenderNodeFn (core.js:11098) at Object.eval [as updateRenderer] (ParentFormComponent.html:3) at Object.debugUpdateRenderer [as updateRenderer] (core.js:11087) at checkNoChangesView (core.js:10442)

ParentFormComponent.html:3 ERROR CONTEXT DebugContext_ {view: Object, nodeIndex: 2, nodeDef: Object, elDef: Object, elView: Object}

this is the line of ParentFormComponent.html:3

 <form [formGroup]="parentForm" (ngSubmit)="submitForm()"> 

Here is my code:

<label class="container">DB     <input #db type="checkbox" name="db" (change)="checkValue(db.name, db.checked)">      <span class="checkmark"></span> </label>  <div *ngIf="db.checked" formGroupName="_monitorDB">     <mat-form-field>         <input matInput placeholder="Server name" formControlName="ServerName">     </mat-form-field>      <mat-form-field>         <input matInput placeholder="DataBase name" formControlName="DbName">     </mat-form-field>      <mat-form-field>         <input matInput placeholder="table name" formControlName="DB_tableName">     </mat-form-field>      <mat-form-field>         <input matInput placeholder="port" formControlName="DbPort">     </mat-form-field>      <mat-form-field>         <input matInput placeholder="Query" formControlName="Query">     </mat-form-field>      <mat-form-field>         <input matInput placeholder="Permissions" formControlName="Premissions">     </mat-form-field>  </div> 

and in the ts file:

checkValue(name:string, event: any){     if (event == true){       this.test.push(name);       if (name =="db"){          this.childForm.get('_monitorDB').get('ServerName').setValidators([Validators.required]);          this.childForm.get('_monitorDB').get('DbName').setValidators([Validators.required]);          this.childForm.get('_monitorDB').get('DB_tableName').setValidators([Validators.required]);          this.childForm.get('_monitorDB').get('DbPort').setValidators([Validators.required]);          this.childForm.get('_monitorDB').get('Query').setValidators([Validators.required]);          this.childForm.get('_monitorDB').get('Premissions').setValidators([Validators.required]);        }      }      else{       const index: number = this.test.indexOf(name);       if (index !== -1) {           this.test.splice(index, 1);           if (name =="db"){             this.childForm.get('_monitorDB').get('ServerName').clearValidators();             this.childForm.get('_monitorDB').get('ServerName').updateValueAndValidity();             this.childForm.get('_monitorDB').get('DbName').clearValidators();             this.childForm.get('_monitorDB').get('DbName').updateValueAndValidity();             this.childForm.get('_monitorDB').get('DB_tableName').clearValidators();             this.childForm.get('_monitorDB').get('DB_tableName').updateValueAndValidity();             this.childForm.get('_monitorDB').get('DbPort').clearValidators();             this.childForm.get('_monitorDB').get('DbPort').updateValueAndValidity();             this.childForm.get('_monitorDB').get('Query').clearValidators();             this.childForm.get('_monitorDB').get('Query').updateValueAndValidity();             this.childForm.get('_monitorDB').get('Premissions').clearValidators();             this.childForm.get('_monitorDB').get('Premissions').updateValueAndValidity();           }       }           }       this.checkboxArr.emit(this.test);  } 
like image 306
Livnat Menashe Avatar asked Dec 23 '18 05:12

Livnat Menashe


People also ask

How do you fix expression has changed after it was checked?

Navigate up the call stack until you find a template expression where the value displayed in the error has changed. Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct component lifecycle hook for your use case.


1 Answers

I faced the same issue and I fixed it by using AfterViewChecked and ChangeDetectorRef:

import { AfterViewChecked, ChangeDetectorRef } from '@angular/core'  export class ClassName implements AfterViewChecked {   constructor(private readonly changeDetectorRef: ChangeDetectorRef) {}    ngAfterViewChecked(): void {     this.changeDetectorRef.detectChanges();   } }  
like image 108
Justin J Avatar answered Sep 29 '22 21:09

Justin J