Validate parent component based on iterated children components

Viewed 125

I have a parent component and in the template, I have a ngFor which generates child components. In this parent template, I have a submit button that should be disabled until all generated child components' validations are true. I mean, in the child component I have 3 fields that I should validate and after all children components are valid the submit button in the parent component should be enabled.

parent.component.html

<div *ngFor="let condition of conditions">
   <child-component></child-component>
</div>
.
.
.
<button>Submit</button>

child.component.html

<form [formGroup]="frmGrp">
   <input type="text" formControlName="name" />
   <input type="text" formControlName="address" />
   <input type="text" formControlName="phone" />
</form>

child.component.ts

export class ChildComponent {
   
   frmGrp: FormGroup;

   constructor(private fb: FormBuilder){
      this.frmGrp = this.fb.group({
         name: ["", Validators.required],
         address: ["", Validators.required],
         phone: ["", Validators.required]
      });
   }
}

What is the best practice to achieve this goal?

1 Answers

Great question. You need a form array, which tracks the state of the child form groups:

Tracks the value and validity state of an array of FormControl, FormGroup or FormArray instances

The above is an excerpt from the angular docs: https://angular.io/api/forms/FormArray#description

In your case, this would look like this:

<div formArrayName="conditionsFormArray">
  <div *ngFor="let condition of conditions; let i=index">
  
  </div>
</div>

Then the valid state of the form array can be accessed via the .valid property on the form array:

 this.conditionsForm = this.fb.group({
      conditions: this.fb.array([]) ,
    });
  
  }
 
  get conditions() : FormArray {
    return this.conditionsForm.get("conditions") as FormArray
  }
conditions.valid // valid state of all form groups here
Related