Home > other >  How do I make sure a nested form group returns an array of objects in Angular?
How do I make sure a nested form group returns an array of objects in Angular?

Time:02-02

I am working on a form with nested form groups in Angular 14.

In form.component.ts I have:

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css'],
})
export class FormComponent {
  public form: FormGroup = new FormGroup({
    first_name: new FormControl('', Validators.required),
    last_name: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email]),
    phone: new FormControl('', Validators.required),

    residences: new FormGroup({
      city: new FormControl(''),
      address: new FormControl(''),
    }),
  });

  constructor() {}

  ngOnInit(): void {}

  public sendFormData() {
    console.log(this.form.value);
  }
}

See Stackblitz HERE.

The problem

I need residences to be an array of objects. Instead, it is an object itself.

How do I fix this problem?

CodePudding user response:

Create a form array:

  public form: FormGroup = new FormGroup({
    first_name: new FormControl('', Validators.required),
    last_name: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email]),
    phone: new FormControl('', Validators.required),

    residences: new FormArray([
      new FormGroup({
        city: new FormControl(''),
        address: new FormControl(''),
      }),
    ]),
  });

  get residencesArray(): FormArray {
    return this.form.get('residences') as FormArray;
  }

In the template:

  <div
    formArrayName="residences"
    *ngFor="let residence of residencesArray.controls; let i = index"
  >
    Residence {{ i   1 }}
    <div [formGroupName]="i">
      <mat-form-field appearance="outline" floatLabel="always">
        <mat-label >City:</mat-label>
        <input  matInput formControlName="city" />
      </mat-form-field>

      <mat-form-field appearance="outline" floatLabel="always">
        <mat-label >Address:</mat-label>
        <input  matInput formControlName="address" />
      </mat-form-field>
    </div>
  </div>

  • Related