Upgraded to Angular 8 from 7 resulted in ExpressionChangedAfterItHasBeenCheckedError on all forms

Viewed 232

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}} &nbsp;
          <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?

0 Answers
Related