Home > Blockchain >  how to use formsArray for multi select in an angular app
how to use formsArray for multi select in an angular app

Time:10-12

I have an angular app and in my form, I have a multi-select. Multiselect value will be stored in an array, therefore I am using angular formsArray.

in my app.component.ts:

{{testForm.value|json}}

<form nz-form [formGroup]="testForm">

  <div>
    <p>Title</p>
    <nz-input formControlName="title"></nz-input>
  </div>

  <div>
    <p>Items</p>
    <nz-select
      [nzMode]="'multiple'"
      [nzPlaceHolder]="'Choose items'"
      formArrayName="items"
      [nzNotFoundContent]="'Item not found'">
      <nz-option
        *ngFor="let item of items"
        [nzLabel]="item.title"
        [nzValue]="item.id">
      </nz-option>
    </nz-select>
  </div>

</form>

and inside the .ts file:

export class AppComponent  {
  testForm: FormGroup;
  items = [
    {
      title: 'Item 1',
      id: 1
    },
    {
      title: 'Item 2',
      id: 2
    }
  ]

  constructor(private fb: FormBuilder) {
    this.testForm = this.fb.group({
      title: '',
      items: this.fb.array([]),
    });
  }

}

However, the problem is that, even though I selected the multiple items, but I am getting an empty array like that:

{ "title": "test", "items": [] }

items, attribute is not filling up with the value from nz-select. I have created an app with this example. Here is the link.

stackblitz app sample

CodePudding user response:

Having multiple values does not mean you have to use formArray. Just change in your html formArrayName="items" to formControlName="items"

<nz-select
  [nzMode]="'multiple'"
  [nzPlaceHolder]="'Choose items'"
  formControlName="items"
  [nzNotFoundContent]="'Item not found'"
>
  <nz-option
    *ngFor="let item of items"
    [nzLabel]="item.title"
    [nzValue]="item.id"
  >
  </nz-option>
</nz-select>

And your ts file have to look like

this.testForm = this.fb.group({
      title: [''],
      items: [[]],
    });

CodePudding user response:

Here is working stackblitz

you can do something like this HTML

<p>{{ orderForm.value | json }}</p>
<div [formGroup]="orderForm">
  <div
    formArrayName="items"
    *ngFor="let item of orderForm.get('items').controls; let i = index"
  >
    <div [formGroupName]="i">
      <input formControlName="title" placeholder="Item title" />
      <input formControlName="name" placeholder="Item name" />
    </div>
  </div>
</div>
<button (click)="addItem()">Add</button>

And Script

import { Component, OnInit } from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  FormArray,
  FormControl,
  Validators,
} from '@angular/forms';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  title = 'formarray';
  orderForm!: FormGroup;
  items!: FormArray;
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.orderForm = new FormGroup({
      items: new FormArray([]),
    });
  }
  createItem(): FormGroup {
    return this.formBuilder.group({
      title: '',
      name: '',
    });
  }
  addItem(): void {
    this.items = this.orderForm.get('items') as FormArray;
    this.items.push(this.createItem());
  }
}

CodePudding user response:

You do not have to use a FormArray in this case:

In your HTML:

<form nz-form [formGroup]="testForm">
  <div>
    <p>Title</p>
    <nz-input formControlName="title"></nz-input>
  </div>

  <div>
    <p>Items</p>
    <nz-select
      [nzMode]="'multiple'"
      [nzPlaceHolder]="'Choose items'"
      formControlName="items" <!-- Use formControlName here -->
      [nzNotFoundContent]="'Item not found'"
    >
      <nz-option
        *ngFor="let item of items"
        [nzLabel]="item.title"
        [nzValue]="item.id"
      >
      </nz-option>
    </nz-select>
  </div>
</form>

In your Component's Typescript:

export class AppComponent {
  testForm: FormGroup;
  items = [
    {
      title: "Item 1",
      id: 1,
    },
    {
      title: "Item 2",
      id: 2,
    },
  ];

  constructor(private fb: FormBuilder) {
    this.testForm = this.fb.group({
      title: [""],
      items: [[]], // initialize as empty array
    });
  }
}

I tried this on your StackBlitz-Link and it did work

  • Related