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.
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