0

I need to iterate through all controls in Formbuilder, and children formbuilders to clear validators and updateValueAndValidity. How can I update answer from here to do so ?

Angular 2: Iterate over reactive form controls

Object.keys(this.form.controls).forEach(key => {
    this.form.controls[key].clearValidators();
    this.form.controls[key].updateValueAndValidity();
  });

This form here has formbuilders within formbuilders, etc. The answer above only affects top level children, not subchildren, etc

this.editSharedForm = this.formBuilder.group({
  'name': [null, [Validators.maxLength(50)]],
  'streetAddress': [null, [Validators.maxLength(50)]],
  'city': [null, [Validators.required,Validators.maxLength(200)]],
  'zipcode': [null, [Validators.maxLength(10)]],
  'phoneNumber': [null, [Validators.maxLength(50)]],
  'emailAddress': [null, [Validators.maxLength(50), Validators.email]],
  'addressChangeReason': this.formBuilder.group({
    'addressChangeReasonId': [null,  [Validators.required, Validators.min(1)]],
    'addressChangeReasonCode': [null, [Validators.required, Validators.maxLength(50)]],
    'addressChangeReasonDescription': [null, [Validators.required, Validators.maxLength(255)]]
  }),
  'addressSource': this.formBuilder.group({
    'sourceOfAddressId': [null, [Validators.required, validatorDropdown]],
    'sourceOfAddressCode': [null, [Validators.required, Validators.maxLength(50)]],
    'sourceOfAddressDescription': [Validators.required, Validators.maxLength(255)]]
  })
});

}

2) Additionally, how can I just target 1 subchild (eg addressChange Reason) if needed ? Following is not working

Object.keys(this.editSharedForm.get('addressChangeReason').controls).forEach(key => {
  this.editSharedForm.controls[key].clearValidators();
  this.editSharedForm.controls[key].updateValueAndValidity();
});

Property 'controls' does not exist on type 'AbstractControl'

1 Answers1

4

So, if you want to call clearValidators and updateValueAndValidity on every nested FormControl, you must loop through all nested FormGroups and FormArrays.

It's quite simple as you can see in this quick example:

clearValidators(formGroup: FormGroup| FormArray): void {
  Object.keys(formGroup.controls).forEach(key => {
    const control = formGroup.controls[key] as FormControl | FormGroup | FormArray;
    if(control instanceof FormControl) {
      console.log(`Clearing Validators of ${key}`);
      control.clearValidators();
      control.updateValueAndValidity()
    } else if(control instanceof FormGroup || control instanceof FormArray) {
      console.log(`control '${key}' is nested group or array. calling clearValidators recursively`);
      this.clearValidators(control);
    } else {
      console.log("ignoring control")
    }
  });

For question 2)

Simply call

clearValidators(this.editSharedForm.get('addressChangeReason'))

https://stackblitz.com/edit/angular-dzsrq8

Roy
  • 7,811
  • 4
  • 24
  • 47
A.Winnen
  • 1,680
  • 1
  • 7
  • 13
  • great, I will take a look at this, also how can I just target one child formbuilder below as in question 2? –  Dec 27 '19 at 20:31
  • simply call `clearValidators(this.editSharedForm.get('addressChangeReason')` – A.Winnen Dec 27 '19 at 20:35
  • hi a winnen, ,have you tried the second part of your answer in stackblitz? receiving error Argument of type abstract control is not assignable to parameter of type, FormGroup FormArray, can you try and update answer? Also I would give this new method a new name, so it does not override collide with original name, I gave points, anyway, please fix if you can, thanks ! –  Jan 13 '20 at 02:12
  • maybe name it clearValidatorsNested? your call, thanks, please try question 2b in your stackblitz, was not working for me –  Jan 13 '20 at 02:13
  • what exactly does not work? you must be sure your AbstractControl is FormGroup or FormArray using type assert. – A.Winnen Jan 13 '20 at 15:56
  • can you just show question 2 as an example in your stackblitz? you'll see what I mean, thanks –  Jan 13 '20 at 18:31
  • someone edited my answer 12 hours ago. i reverted it, so it will show the correct solution again. see https://stackblitz.com/edit/angular-cldrx3 – A.Winnen Jan 13 '20 at 19:45
  • You made my day. Thank you so much for your answer. it is helping me out for fixing bug in production. Thank you. – Mayur Kukadiya Aug 13 '21 at 06:40