I have a angular application and i upgraded it from angualr 7 to angular 8 and started to get this error on all my forms, which is wierd because it worked when i was on angular 7, i never got this error.
The error:
ClaimHeaderComponent.html:24 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it
was checked. Previous value: 'ng-untouched: true'. Current value:
'ng-untouched: false'.
at viewDebugError (core.js:28792)
at expressionChangedAfterItHasBeenCheckedError (core.js:28769)
at checkBindingNoChanges (core.js:29757)
at checkNoChangesNodeInline (core.js:44446)
at checkNoChangesNode (core.js:44415)
at debugCheckNoChangesNode (core.js:45376)
at debugCheckRenderNodeFn (core.js:45308)
at Object.eval [as updateRenderer] (ClaimHeaderComponent.html:24)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:45293)
at checkNoChangesView (core.js:44250)
A sample of my code of a form that worked in Angular 7 but not in Angular 8
ts file
@Input() cMasterForm: FormGroup;
private _errorMsgProvClaim: string;
private _errorMsgEzAuth: any;
private _errorMsgEzProv: any;
private _errorMsgMemb: any;
private _errorMsgClaimType: any;
private _errorMsgRefProv: any;
private _errorMsgDepMem: any;
public _errorMsg: ValidationErrors;
private _errorMsgRecdate: any;
constructor(private fb: FormBuilder, public _appService: AppService) {
this._errorMsg = {
required: 'This field is required!',
maxLength: 'Field Length Exceeded!',
minLength: 'Field Length To Short!',
familyNumber: 'Please complete a family number field first!',
valid: 'valid',
invalid: 'Invalid Format!'
};
}
ngOnInit() {
this.cMasterForm = this.fb.group({
provclaim: ['', [Validators.required, Validators.maxLength(20)]],
ezcapauth: ['', [Validators.maxLength(16)]],
ezcapprov: ['', [Validators.required, Validators.maxLength(20)]],
ezcapmemb: ['', [Validators.required, Validators.maxLength(20)]],
ezcapdepmemb: ['', [Validators.required, Validators.maxLength(20)]],
reprovider: ['', [Validators.maxLength(20)]],
vendoid: [],
PHC: [],
PlaceSelect: [],
CTOpt: [],
HPCode: [],
RecDateField: ['', Validators.required]
});
this.cMasterForm.disable();
this._appService.ClaimCaptureService.btnClick = false;
this._appService.ClaimCaptureService.enableWizardNext = false;
this.cMasterForm.valueChanges.subscribe(
(changes) => {
this.ValidateForm(changes);
});
}
public get errorMsgProvClaim(): string {
return this._errorMsgProvClaim;
}
public set errorMsgProvClaim(value: string) {
this._errorMsgProvClaim = value;
}
public get errorMsgEzAuth(): any {
return this._errorMsgEzAuth;
}
public set errorMsgEzAuth(value: any) {
this._errorMsgEzAuth = value;
}
public get errorMsgEzProv(): any {
return this._errorMsgEzProv;
}
public set errorMsgEzProv(value: any) {
this._errorMsgEzProv = value;
}
public get errorMsgMemb(): any {
return this._errorMsgMemb;
}
public set errorMsgMemb(value: any) {
this._errorMsgMemb = value;
}
public get errorMsgClaimType(): any {
return this._errorMsgClaimType;
}
public set errorMsgClaimType(value: any) {
this._errorMsgClaimType = value;
}
public get errorMsgRefProv(): any {
return this._errorMsgRefProv;
}
public set errorMsgRefProv(value: any) {
this._errorMsgRefProv = value;
}
public get errorMsgDepMem(): any {
return this._errorMsgDepMem;
}
public set errorMsgDepMem(value: any) {
this._errorMsgDepMem = value;
}
public get errorMsgRecdate(): any {
return this._errorMsgRecdate;
}
public set errorMsgRecdate(value: any) {
this._errorMsgRecdate = value;
}
ValidateForm(changes: any) {
if (this.cMasterForm.get('ezcapprov').dirty === true) {
this.ValidateEzcapProv();
}
if ((this.cMasterForm.get('ezcapmemb').dirty === true)) {
this.ValidateEzcapMemb();
}
if ((this.cMasterForm.get('ezcapdepmemb').dirty === true)) {
this.ValidateEzcapDep();
}
if (this.cMasterForm.get('reprovider').dirty === true) {
this.ValidateRefProv();
}
if (this.cMasterForm.get('ezcapauth').dirty === true) {
this.ValidateEzcapAuth();
}
}
FieldValidation(fieldName: string, controlName: string) {
if ((fieldName === undefined) || (fieldName === '') || (fieldName === null)) {
this.cMasterForm.get(controlName).setErrors(this._errorMsg['required']);
return this._errorMsg['required'];
}
if (fieldName.length > 20) {
this.cMasterForm.get(controlName).setErrors(this._errorMsg['maxLength']);
return this._errorMsg['maxLength'];
}
if ((controlName == 'ezcapprov') || (controlName =='reprovider')) {
if (fieldName.length > 7) {
return this._errorMsg['maxLength']
}
if (fieldName.length < 7) {
return this._errorMsg['minLength']
}
let x = parseInt(fieldName);
if (x.toString() == 'NaN') {
return this._errorMsg['invalid'];
}
}
this.cdr.detectChanges()
return this._errorMsg['valid'];
}
PHCODEChanged() {
let y = this.cMasterForm.get('PHC').value.charAt(0);
this._appService.ClaimCaptureService.currentClaimHeader.PHCODE = y;
}
ClaimTypeChanged() {
let z = this.cMasterForm.get('CTOpt').value.charAt(0);
this._appService.ClaimCaptureService.currentClaimHeader.CLAIMTYPE = z;
let x = this.cMasterForm.get('CTOpt').value.charAt(0);
let y = this.cMasterForm.get('ezcapmemb').value;
if (x !== "M") {
this._appService.ClaimCaptureService.currentClaimHeader.VENDORID = this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV;
this._appService.ClaimCaptureService.vedorFieldVissible = true;
} else {
this._appService.ClaimCaptureService.currentClaimHeader.VENDORID = 'M' + y;
this._appService.ClaimCaptureService.vedorFieldVissible = false;
}
this._appService.ClaimCaptureService._bankingPrompt = true;
}
HpCodeChanged() {
this._appService.ClaimCaptureService.currentClaimHeader.hpCode = this.cMasterForm.get('HPCode').value;
this._appService.ClaimCaptureService.currentClaimDetail.hpCode = this._appService.ClaimCaptureService.currentClaimHeader.hpCode;
this._appService.ClaimCaptureService.LoadPhCodes();
}
PlcSrvChanged() {
let x = this.cMasterForm.get('PlaceSelect').value;
this._appService.ClaimCaptureService.currentClaimHeader.PLACE = x;
}
VendIdChanged() {
let x = this.cMasterForm.get('vendoid').value;
this._appService.ClaimCaptureService.currentClaimHeader.VENDORID = x;
}
ValidateProvClaim() {
this._appService.ClaimCaptureService.currentClaimHeader.PROVCLAIM = this.cMasterForm.get('provclaim').value;
this.errorMsgProvClaim = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.PROVCLAIM, 'provclaim');
if (this.errorMsgProvClaim === 'valid') {
this.errorMsgProvClaim = this.cMasterForm.get('provclaim').value;
}
}
ValidateEzcapAuth() {
this._appService.ClaimCaptureService.currentClaimHeader.EZCAPAUTH = this.cMasterForm.get('ezcapauth').value;
this.errorMsgEzAuth = '';
}
ValidateEzcapProv() {
this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV = this.cMasterForm.get('ezcapprov').value;
this.errorMsgEzProv = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV, 'ezcapprov');
if (this.errorMsgEzProv === 'valid') {
this.errorMsgEzProv = this._appService.ClaimCaptureService.DataBaseCheckEzcapProv();
let v = this.errorMsgEzProv;
if (this.errorMsgEzProv !== 'Practice Number is incorrect') {
this.cMasterForm.get('ezcapprov').setErrors(null);
this._appService.ClaimCaptureService.currentClaimHeader.VENDORID = this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV;
this._appService.ClaimCaptureService.vedorFieldVissible = true;
this._appService.ClaimCaptureService.currentClaimHeader.REFPROVID = this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV;
} else {
this.errorMsgEzProv = '';
this.errorMsgEzProv = this.cMasterForm.get('ezcapprov').value;
this._appService.ClaimCaptureService.currentClaimHeader.VENDORID = this._appService.ClaimCaptureService.currentClaimHeader.EZCAPPROV;
this._appService.ClaimCaptureService.vedorFieldVissible = false;
}
this.cMasterForm.get('ezcapprov').markAsPristine();
} else {
this.cMasterForm.get('ezcapprov').setErrors(this.errorMsgEzProv);
}
}
ValidateEzcapMemb() {
this.errorMsgMemb = 'Checking...';
this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB = this.cMasterForm.get('ezcapmemb').value;
this.errorMsgMemb = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB, 'ezcapmemb');
if (this.errorMsgMemb === 'valid') {
this.errorMsgMemb = this._appService.ClaimCaptureService.DataBaseCheckEzcapMemb();
if (this.errorMsgMemb !== 'Family Number is incorrect') {
this.cMasterForm.get('ezcapmemb').setErrors(null);
if ((this.cMasterForm.get('ezcapdepmemb').value !== null) && (this.cMasterForm.get('ezcapdepmemb').value !== '')
&& (this.cMasterForm.get('ezcapdepmemb').value !== undefined)) {
this.ValidateEzcapDep();
}
} else {
this.cMasterForm.get('ezcapmemb').setErrors(this.errorMsgMemb);
}
}
}
ValidateEzcapDep() {
this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB = this.cMasterForm.get('ezcapmemb').value;
this._appService.ClaimCaptureService.currentClaimHeader.membDepCode = this.cMasterForm.get('ezcapdepmemb').value;
this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB = this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB + '-' + this._appService.ClaimCaptureService.currentClaimHeader.membDepCode;
this.errorMsgDepMem = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.EZCAPMEMB, 'ezcapdepmemb');
if ((this.cMasterForm.get('ezcapmemb').value === '') || (this.cMasterForm.get('ezcapmemb').value === null)) {
this.errorMsgDepMem = this._errorMsg['familyNumber'];
this.cMasterForm.get('ezcapdepmemb').setErrors(this.errorMsgDepMem);
} else {
if (this.errorMsgDepMem === 'valid')
this.errorMsgDepMem = this._appService.ClaimCaptureService.DataBaseCheckEzcapDepMemb();
if (this.errorMsgDepMem !== 'Dependant Number is incorrect') {
this.cMasterForm.get('ezcapdepmemb').setErrors(null);
} else {
this.cMasterForm.get('ezcapdepmemb').setErrors(this.errorMsgMemb);
}
}
}
ValidateRefProv() {
this._appService.ClaimCaptureService.currentClaimHeader.REFPROVID = this.cMasterForm.get('reprovider').value;
this.errorMsgRefProv = '';
if ((this._appService.ClaimCaptureService.currentClaimHeader.REFPROVID !== '') && (this._appService.ClaimCaptureService.currentClaimHeader.REFPROVID !== null)) {
this.errorMsgRefProv = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.REFPROVID, 'reprovider');
if (this.errorMsgRefProv === 'valid') {
this.errorMsgRefProv = this._appService.ClaimCaptureService.DataBaseCheckRefProv();
if (this.errorMsgRefProv !== 'Reffering Practice Number is incorrect') {
this.cMasterForm.get('reprovider').setErrors(null);
} else {
this.cMasterForm.get('reprovider').setErrors(null);
this.errorMsgRefProv = this.cMasterForm.get('reprovider').value
}
this.cMasterForm.get('reprovider').markAsPristine();
} else {
this.cMasterForm.get('reprovider').setErrors(this.errorMsgRefProv);
}
}
}
SetDefaultDropDownValues() {
//Default for place of Service if none is selected
let p = this._appService.ClaimCaptureService.currentClaimHeader.PLACE;
this.cMasterForm.get('PlaceSelect').setValue(p);
//Default for phCode when none is selected
let ph = this._appService.ClaimCaptureService.phSelect[0];
this.cMasterForm.get('PHC').setValue(ph);
}
public ClearFormOnNew() {
this._appService.ClaimCaptureService.DefaultDate = '';
this.cMasterForm.reset();
this.errorMsgClaimType = '';
this.errorMsgEzAuth = '';
this.errorMsgEzProv = '';
this.errorMsgMemb = '';
this.errorMsgProvClaim = '';
this.errorMsgRefProv = '';
this.errorMsgDepMem = '';
this.cMasterForm.enable();
this._appService.ClaimCaptureService.NewClaimMaster();
this.SetDefaultDropDownValues();
this._appService.ClaimCaptureService.btnClick = true;
this.cMasterForm.controls['HPCode'].setValue(this._appService.ClaimCaptureService.HpCodesList[0].code, { onlySelf: true });
this._appService.ClaimCaptureService.LoadPhCodes();
this.cMasterForm.get('PlaceSelect').disable();
this._appService.ClaimCaptureService._disableBack = false;
}
public DisableOnCancel() {
this.cMasterForm.reset();
this.errorMsgClaimType = '';
this.errorMsgEzAuth = '';
this.errorMsgEzProv = '';
this.errorMsgMemb = '';
this.errorMsgProvClaim = '';
this.errorMsgRefProv = '';
this.errorMsgDepMem = '';
this._appService.ClaimCaptureService.currentClaimHeader = new Recordtype1Model();
this.cMasterForm.disable();
this._appService.ClaimCaptureService.btnClick = false;
}
SaveData() {
if (this._appService.ClaimCaptureService.dataBaseMessageProv == 'Practice Number is incorrect') {
this._appService.ClaimCaptureService._incorrect = true;
} else {
this.cMasterForm.disable();
this._appService.ClaimCaptureService.SaveClaimMaster();
this._appService.ClaimCaptureService._incorrect = false;
}
}
EditData() {
this.cMasterForm.enable();
this._appService.ClaimCaptureService.btnClick = true;
this.cMasterForm.get('PlaceSelect').disable();
}
ValidaterecDateField() {
if ((this.cMasterForm.get('RecDateField').value === '')
|| (this.cMasterForm.get('RecDateField').value === null)
|| (this.cMasterForm.get('RecDateField').value === undefined)) {
this.errorMsgRecdate = this._errorMsg['required'];
} else {
this._appService.ClaimCaptureService.currentClaimHeader.DATERECD = new Date(this.cMasterForm.get('RecDateField').value).toDateString();
this.errorMsgRecdate = this.FieldValidation(this._appService.ClaimCaptureService.currentClaimHeader.DATERECD, 'RecDateField');
if (this.errorMsgRecdate === 'valid') {
this.errorMsgRecdate = ' ';
this.PopulateFromDateErr();
}
if (this.errorMsgRecdate !== '') {
this.cMasterForm.get('RecDateField').setErrors(this.errorMsgRecdate);
}
}
}
PopulateFromDateErr() {
let ToDay: Date = new Date;
let comparedDate = new Date(this._appService.ClaimCaptureService.currentClaimHeader.DATERECD);
if (comparedDate.toString().includes('Invalid Date')) {
this.errorMsgRecdate = 'Entered date is invalid.';
} else {
if (comparedDate > ToDay) {
this.errorMsgRecdate = 'Chosen date cannot be greater than ' + ToDay.toLocaleString();
} else {
this._appService.ClaimCaptureService.DefaultDate = this.cMasterForm.get('RecDateField').value;
this.errorMsgRecdate = '';
}
}
}
VerifiedProv() {
this.cMasterForm.disable();
this._appService.ClaimCaptureService.SaveClaimMaster();
this._appService.ClaimCaptureService._incorrect = false;
}
}
My html form
<form clrForm [formGroup]="cMasterForm" clrLayout="compact">
<div>
<button class="btn btn-success btn-sm" type="submit" (click)="this.SaveData()" [disabled]="!this.cMasterForm.valid">Save</button>
<button class="btn btn-warning btn-sm" [disabled]="!this._appService.ClaimCaptureService.btnClick" (click)="this.DisableOnCancel()">Cancel</button>
<button class="btn btn-primary btn-sm" type="submit" (click)="ClearFormOnNew()" [disabled]="this._appService.ClaimCaptureService.btnClick">New</button>
<button class="btn btn-Secondary btn-sm" type="submit" (click)="EditData()" [disabled]="this._appService.ClaimCaptureService.btnClick">Edit</button>
</div>
<div class="clr-row">
<div class="clr-col-6">
<clr-select-container>
<label>Health Plan</label>
<select clrSelect formControlName="HPCode" (change)="this.HpCodeChanged()">
<option *ngFor="let list of this._appService.ClaimCaptureService.HpCodesList" [ngValue]="list.code">{{list.name}}</option>
</select>
</clr-select-container>
<clr-select-container>
<label>Type</label>
<select clrSelect formControlName="PHC" (change)="this.PHCODEChanged()">
<option *ngFor="let code of this._appService.ClaimCaptureService.phSelect" [ngValue]="code">{{code}}</option>
</select>
</clr-select-container>
<clr-input-container>
<label>
Practice Number
</label>
<input tabindex="3" clrInput type="text" (blur)=" ValidateEzcapProv()" formControlName="ezcapprov" required />
<clr-control-error>{{this.errorMsgEzProv}}</clr-control-error>
<clr-control-helper style="color:rgb(4, 161, 70)">
{{this.errorMsgEzProv}}
<a href="..." role="tooltip" aria-haspopup="true" class="tooltip tooltip-lg tooltip-bottom-right">
<clr-icon shape="info-circle" size="20"></clr-icon>
<span tabindex="-1" class="tooltip-content">All practice numbers will be validated, even if it was not found, since it could be a new provider.</span>
</a>
</clr-control-helper>
</clr-input-container>
<clr-input-container>
<label>Referring Practice Number</label>
<input clrInput tabindex="4" type="text" (blur)="ValidateRefProv()" formControlName="reprovider" />
<clr-control-error>{{this.errorMsgRefProv}}</clr-control-error>
<clr-control-helper style="color:rgb(4, 161, 70)">{{this.errorMsgRefProv}}</clr-control-helper>
</clr-input-container>
<clr-select-container *ngIf="this._appService.ClaimCaptureService.vedorFieldVissible" >
<label>Group Practice</label>
<select clrSelect formControlName="vendoid" (change)="VendIdChanged()">
<option *ngFor="let id of this._appService.ClaimCaptureService.vendorIds" [ngValue]="id.vendor">{{id.displayItem}}</option>
</select>
</clr-select-container>
</div>
<div class="clr-col-6">
<clr-select-container [hidden]="true">
<label>Place</label>
<select clrSelect formControlName="PlaceSelect" (change)="PlcSrvChanged()" >
<option *ngFor="let place of this._appService.ClaimCaptureService.plcSvcList" [ngValue]="place.code">{{place.descr}}</option>
</select>
</clr-select-container>
<clr-input-container>
<label>Family Number</label>
<input clrInput type="text" (blur)="ValidateEzcapMemb()" formControlName="ezcapmemb"
required />
<clr-control-error>{{this.errorMsgMemb}}</clr-control-error>
<clr-control-helper style="color:rgb(4, 161, 70)">{{this.errorMsgMemb}}</clr-control-helper>
</clr-input-container>
<clr-input-container>
<label>Dependant Code</label>
<input clrInput type="text" (blur)="ValidateEzcapDep()" formControlName="ezcapdepmemb"
required />
<clr-control-error>{{this.errorMsgDepMem}}</clr-control-error>
<clr-control-helper style="color:rgb(4, 161, 70)">{{this.errorMsgDepMem}}</clr-control-helper>
</clr-input-container>
<clr-input-container>
<label>Account Number</label>
<input clrInput type="text" (blur)="ValidateProvClaim()" formControlName="provclaim" />
<clr-control-error>{{this.errorMsgProvClaim}}</clr-control-error>
<clr-control-helper style="color:rgb(4, 161, 70)">{{this.errorMsgProvClaim}}</clr-control-helper>
</clr-input-container>
<clr-date-container>
<label>Date Received</label>
<input type="date" clrDate formControlName="RecDateField" (blur)="ValidaterecDateField()" />
<clr-control-error>{{this.errorMsgRecdate}}</clr-control-error>
</clr-date-container>
<clr-select-container>
<label>Payment to</label>
<select clrSelect formControlName="CTOpt" (change)="this.ClaimTypeChanged()">
<option *ngFor="let ctype of this._appService.ClaimCaptureService.ctSelect" [ngValue]="ctype" [disabled]="!(this.cMasterForm.get('ezcapprov').valid && this.cMasterForm.get('ezcapmemb').valid)">{{ctype}}</option>
</select>
</clr-select-container>
<clr-input-container>
<label>Auth Number</label>
<input clrInput type="text" (blur)="ValidateEzcapAuth()" formControlName="ezcapauth" />
<clr-control-error>{{this.errorMsgEzAuth}}</clr-control-error>
<clr-control-helper style="color:cornflowerblue">*This Field is Optional</clr-control-helper>
<clr-control-helper style="color:rgb(4, 161, 70)">{{this.errorMsgEzAuth}}</clr-control-helper>
</clr-input-container>
</div>
</div>
</form>
I dont know if im doing something wrong or as to why it worked in Angular 7 but in 8 i get the error after every blur/check i do in my form.
what i did try though was to insert the following in my components constructor
private cdr: ChangeDetectorRef
and then call the detectChanges() method after every validation i do which seemed to get rid of the error.
so in conclusion my question is why i started getting the above mentioned error when i upgraded to angular 8 and is there any other way to get rid of the error than the above mentioned way?