Home > Software engineering >  How to push FormGroup into FormArray?
How to push FormGroup into FormArray?

Time:09-27

I would like to push dynamic values into a form.

<div formArrayName="details">
  <div *ngFor="let detail of _detailRowNumber; index as i">
    <mat-form-field appearance="fill">
      <mat-label>Label of a detail</mat-label>
      <input id="detail-label" matInput type="text" formControlName="label">
    </mat-form-field>

    <mat-form-field appearance="fill">
      <mat-label>Description of a detail</mat-label>
      <input id="detail-description" matInput type="text" formControlName="description">
    </mat-form-field>

    <button type="button" *ngIf="_detailRowNumber.length > 1" (click)="decreaseDetailRow(detail)" mat-fab color="primary" aria-label="Remove a new row from the detail list">
      <mat-icon>remove</mat-icon>
    </button>

    <button type="button" (click)="increaseDetailRow(i)" mat-fab color="primary" aria-label="Add a new row to the detail list">
      <mat-icon>add</mat-icon>
    </button>
  </div>
</div>
details: FormGroup = new FormGroup({
    label: new FormControl(''),
    description: new FormControl('')
});

formMain = this.fb.group({
  details: this.details
});

So far, it works fine. So my control looks like this:

details: {
  label: "my label",
  description: "my description"
}

But when I click on the Add button, new input fields will be added and their values I want to push to the form as well.

This is what I have tried:

increaseDetailRow(index: number): void {
  this._detailRowNumber.splice(  index, 0, Date.now());
  (this.formMain.controls['details'] as FormArray).push(this.details);
}

But I get the error:

this.formMain.controls.details.push is not a function

Instead of details: this.details, I have also tried it with details: new FormArray([]). but then I get this error:

Cannot find control with path: 'details -> label'

CodePudding user response:

You can use the following code to get it working. I used a FormBuilder where an array of form groups was created.

your.component.ts

export class YourComponent {
  form = this.fb.array([
    new FormGroup({
      label: new FormControl(),
      description: new FormControl(),
    }),
  ]);

  constructor(private fb: FormBuilder) {}

  increaseDetailRow(): void {
    this.form.push(
      new FormGroup({
        label: new FormControl(),
        description: new FormControl(),
      })
    );
  }

  decreaseDetailRow() {
    this.form.controls.pop();
  }
}

your.component.html


<div *ngFor="let detail of form.controls; index as i">

  <form [formGroup]="detail">
    <mat-form-field appearance="fill">
      <mat-label>Label of a detail</mat-label>
      <input id="detail-label" matInput type="text" formControlName="label">
    </mat-form-field>

    <mat-form-field appearance="fill">
      <mat-label>Description of a detail</mat-label>
      <input id="detail-description" matInput type="text" formControlName="description">
    </mat-form-field>
  </form>

</div>

<button type="button" *ngIf="form.length >= 1" (click)="decreaseDetailRow()" mat-fab color="primary" aria-label="Remove a new row from the detail list">
  <mat-icon>remove</mat-icon>
</button>

<button type="button" (click)="increaseDetailRow()" mat-fab color="primary" aria-label="Add a new row to the detail list">
  <mat-icon>add</mat-icon>
</button>


  • Related