Angular 4 array validation

20,369

Your getters for name and info actually don't target the specific form controls, since your person is a formArray, for example this.form.get('person.name'); does not exist in your form. What you need to do, is use the iteration for each formgroup and target that group with its controls, so your template should look like this:

<div *ngFor="let p of form.controls.person.controls; let i = index" 
             [formGroupName]="i">
  <label for="name">name:</label>
  <input formControlName="name" id="name" type="text">
  <!-- check if the name in this group has the error -->
  <div *ngIf="p.controls.name.dirty">
    <div *ngIf="p.hasError('required', 'name')">Required</div>  
  </div>
</div>

DEMO


Furthermore a suggestion is, that you can shorten your code a bit and remove a method that isn't really needed for initializing/adding formgroup to your array, so here I removed the addNewRow, initItemRows can be called when you want a new row added.

this.form = this.fb.group({
  person: this.fb.array([])
});
this.initItemRows();

initItemRows() {
  let ctrl = <FormArray>this.form.controls.person;
  ctrl.push(this.fb.group({
    name: ['', Validators.required],
    info: ['', Validators.required]      
  }))
}
Share:
20,369
Jiří Přibil
Author by

Jiří Přibil

Updated on July 09, 2022

Comments

  • Jiří Přibil
    Jiří Přibil almost 2 years

    I need help with formArray validation in reactive form. I want validate each item in array, but i have no idea how can i do that. Thanks.

    html code:

        <label for="name">name:</label>
        <input formControlName="name" id="name" type="text">
        <div *ngIf="name.invalid && (name.dirty || name.touched)">
           <div *ngIf="name.errors.required">
             required
           </div>
        </div>
    

    TypeScript code:

     createForm() {
        this.form = this.fb.group({
          person: this.fb.array([this.initItemRows()])
        });
      }
    
    initItemRows() {
        return this.fb.group({
          name: [''],
          info: ['']
        });
      }
    
      addNewRow() {
        const control = <FormArray>this.form.controls['person'];
        control.push(this.initItemRows());
      }
    
      deleteRow(index: number) {
        const control = <FormArray>this.form.controls['person'];
        control.removeAt(index);
      }
    
      get name() { return this.form.get('person.name'); }
      get info() { return this.form.get('person.info'); }
    

    I tried this:

    initItemRows() {
        return this.fb.group({
          name: ['', Validators.required ],
          info: ['', Validators.required ]
        });
      }
    

    It doesnt work..

  • Ruben
    Ruben almost 6 years
    thanks, this should be in the angular documention though