Reputation: 241
Good Day.
I looked for the solution, and even though there are a view similar question to what I am asking, I am sure this one is a bit more unique and not a duplicate.
here is my html form:
<div class="form-group col-md-6" formGroupName="schema">
<div formArrayName="currencies">
<input type="text" class="form-control" id="percentage" formControlName="percentage" placeholder="Discount %*" required>
</div>
</div>
and here is my ts formBuilder.
this.createPromo = this.fb.group({
type: ['promotion'],
name: ['', Validators.required],
description: ['', Validators.required],
enabled: ['', Validators.required],
promotion_type: ['', Validators.required],
start: ['', Validators.required],
end: ['', Validators.required],
schema: this.fb.group({
currencies: this.fb.array([
this.fb.group({
percentage: '',
currency: 'ZAR'
})
])
}),
});
So I want my form to submit as a grouped array. However the error in the console is the following Cannot find control with path: 'schema -> currencies -> percentage'
, thus I am not able to submit my form as percentage
is empty even after I input a number.
Upvotes: 6
Views: 13111
Reputation: 39482
You'll need the following for your scenario:
div
with formGroupName="schema"
.div
with formArrayName="currencies"
.div
with ngFor="let currencyGroup of currencyFormGroups; let i = index;"
. Notice that currencyFormGroups
is a getter in your Component Class.div
with [formGroupName]="i"
where i
is the index that we created on the fly within *ngFor
.input
s with formControlName="percentage"
and formControlName="currency"
respectively..
Here's all these steps translated to code:
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
createPromo: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.createPromo = this.fb.group({
'type': ['type'],
name: ['name', Validators.required],
description: ['description', Validators.required],
enabled: ['enabled', Validators.required],
promotion_type: ['promotion_type', Validators.required],
start: ['start', Validators.required],
end: ['end', Validators.required],
schema: this.fb.group({
currencies: this.fb.array([
this.fb.group({
percentage: 'percentage',
currency: 'ZAR'
}),
this.fb.group({
percentage: 'percentage',
currency: 'INR'
}),
])
}),
});
}
get currencyFormGroups() {
return (<FormArray>(<FormGroup>this.createPromo.get('schema')).get('currencies')).controls;
}
}
Template:
<form [formGroup]="createPromo">
...
<div formGroupName="schema">
<div formArrayName="currencies">
<div *ngFor="let currencyGroup of currencyFormGroups; let i = index;">
<div [formGroupName]="i">
<input
type="text"
name="percentage"
formControlName="percentage">
<input
type="text"
name="currency"
formControlName="currency">
</div>
</div>
</div>
</div>
</form>
Here's a Sample StackBlitz for your ref.
PS: For simplicity's sake, I've considered all the form controls as input
. Please make your changes accordingly.
Upvotes: 13