angulartypescriptform-controlformgroupsangular-validator

Angular 6, this.formGroup.updateValueAndValidity() not working properly


I am trying to add and remove validators in a formGroup controls based on certain condition.

When I am updating the validators through formGroup.updateValueAndValidity() for whole form its not updating, where as if I am specifically applying for each Control i.e. formGroup.get('formControl').updateValueAndValidity(), it is working but i have to write for each control which is i hope not the correct way. What am i doing wrong?

if (data == 'x') {
    this.myForm.get('control2').setValue(null);
    this.myForm.get('control2').setValidators(Validators.nullValidator);
    this.myForm.get('control1').setValidators(Validators.required);
} else if (data == 'y') {
    this.myForm.get('control1').setValue(null);
    this.myForm.get('control1').setValidators(Validators.nullValidator);
    this.myForm.get('control2').setValidators(Validators.required);
}
this.myForm.get('control1').updateValueAndValidity();
this.myForm.get('control2').updateValueAndValidity();

this is working, but,

this.myForm.updateValueAndValidity();

this is not working.


Solution

  • updateValueAndValidity() is bottom-up, so if you call this method over a control, it will check only validations of this control and their parents, but not their children.

    For more details, see AbstractControl#updateValueAndValidity on github to how it works.

      updateValueAndValidity(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
        this._setInitialStatus();
        this._updateValue();
    
        if (this.enabled) {
          this._cancelExistingSubscription();
          (this as{errors: ValidationErrors | null}).errors = this._runValidator();
          (this as{status: string}).status = this._calculateStatus();
    
          if (this.status === VALID || this.status === PENDING) {
            this._runAsyncValidator(opts.emitEvent);
          }
        }
    
        if (opts.emitEvent !== false) {
          (this.valueChanges as EventEmitter<any>).emit(this.value);
          (this.statusChanges as EventEmitter<string>).emit(this.status);
        }
    
        if (this._parent && !opts.onlySelf) {
          this._parent.updateValueAndValidity(opts);
        }
      }