Reputation: 1219
Here is my FormGroup:
this.productGroup = this.fb.group({
name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])],
desc: ['', Validators.maxLength(3000)],
category: ['', Validators.required]
variants: this.fb.array([
this.fb.group({
type: '',
options: ''
})
])
});
I need to dinamically add type
and options
control fields after the user click on a button. FormArray should look like this after User Input:
[ {type: 'size', options: 'Small', 'Big'}, {type: 'color', options: 'red', 'blue, 'yellow'}, ... ]
.
Here whats I'm trying to do:
// Add new item to FormArray
addItem(): void {
this.variantsArray = this.productGroup.get('variants') as FormArray;
this.variantsArray.push(this.fb.group({
type: '',
options: ''
}));
}
// Template
<form [formGroup]="productGroup">
// inputs...
<div formArrayName="variants" *ngFor="let item of productGroup.controls['variants']; let i = index;">
<div [formGroupName]="i">
<div class="row">
<mat-form-field class="col-12">
<input formControlName="type">
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="col-12">
<input formControlName="options">
</mat-form-field>
</div>
</div>
<div class="row">
<a href="javascript:" (click)="addItem()"> Adicionar Variante </a>
<a href="javascript:" (click)="removeItem(i)" *ngIf="i > 0"> Remover Variante </a>
</div>
</div>
</form>
How to make it work?
Upvotes: 1
Views: 630
Reputation: 575
I don't know exactly what you want to achieve but I think I got your problem.
The following code:
variants: this.fb.array([
this.fb.group({
type: '',
options: ''
})
])
does not produce an array, so you can't iterate over it with *ngFor
.
If you look a little deeper into it you will see that
productGroup.controls['variants']
has a property with the controls.
So just change the *ngFor
to:
*ngFor="let item of productGroup.controls['variants'].controls; let i = index;"
and you should be fine.
Upvotes: 1
Reputation: 8468
For adding the formElemnt dynamically in the reactive form, you need to first create the form element or a form group and push it in the original formarry for that field.
EX: i have a customerForm like below
this.customerForm = this.fb.group({
firstName: ['', [Validators.required, Validators.minLength(3)]],
lastName: ['', [Validators.required, Validators.maxLength(50)]],
emailGroup: this.fb.group({
email: ['', [Validators.required, Validators.email]],
confirmEmail: ['', Validators.required],
}, { validator: emailMatcher }),
phone: ''
addresses: this.fb.array([this.createAddress()])
});
On click of add Address in View I can call a function in component that will push a new address to the addresses array in form.
addAddress(): void {
this.addresses.push(this.createAddress());
}
createAddress(): FormGroup {
return this.fb.group({
street1: ['', Validators.required],
street2: '',
city: '',
state: '',
zip: ''
});
}
In your view you can iterate over this address array and display the addresses. Initially it won't show as the array value will be empty! Hope it Helps.
Upvotes: 0