Reputation: 1783
I use Formbuilder to create a FormGroup:
myForm = this.fb.group(
{
title: [""],
fixed_grade1: [""],
fixed_value1: [""],
fixed_grade2: [""],
fixed_value2: [""],
fixed_grade3: [""],
fixed_value3: [""],
fixed_grade4: [""],
fixed_value4: [""]
});
all the fixed_grade
and fixed_value
are inputs and dropdowns.
I have 4 pairs of them, and this works correctly.
But now I would like to group these, so I don't have to access each value in my controller one by one, with myForm.get("fixed_grade1").value
for each one.
But I would like that all these value are grouped in an array like:
myArray: [{grade, value}, [grade, value}...]
so I can access their value by: myArray[0].grade
Instead of mapping each single value to a new array, I saw there is a FormArray
in FormBuilder
, I just don't seem to be able to implement it correclty.
What would be the correct syntax to achieve what I described, having exactly 4 pairs of grade/score, and also it's important that in my final array with all these pairs grade/score, I have only the values that are not undefined, so if in my form the user only fills one pair grade/score, then my myArray.length
will be 1.
Upvotes: 2
Views: 9823
Reputation: 39432
You have defined your FormGroup
wrong. Your FormGroup
should have had a FormArray
of FormGroup
s. Inside each of these FormGroup
s there should have been two FormControl
s for grade
and value
.
Change your form to this:
const grades = [
{grade: 'Grade 1', value: 'Value 1'},
{grade: 'Grade 2', value: 'Value 2'},
{grade: 'Grade 3', value: 'Value 3'},
{grade: 'Grade 4', value: 'Value 4'}
]
myForm = this.fb.group({
title: [],
grades: this.fb.array(this.grades.map(grade => this.fb.group({
grade: [grade.grade],
value: [grade.value]
}))),
});
// OR
myForm = this.fb.group({
title: [],
grades: this.fb.array(this.grades.map(grade => this.fb.group({
grade: [],
value: []
}))),
});
...
get gradesArray() {
return (<FormArray>this.myForm.get('grades')).controls;
}
...
getArrayGroupControlByIndex(index) {
return (<FormArray>this.myForm.get('grades'))
.at(index);
}
This is how you'll use it in the template:
<form [formGroup]="myForm">
<input type="text" formControlName="title">
<br>
<div formArrayName="grades">
<div *ngFor="let gradeGroup of gradesArray; let i = index;">
<div [formGroupName]="i">
Group {{ i + 1 }}
<input type="text" formControlName="grade">
<input type="text" formControlName="value">
</div>
<br>
</div>
</div>
</form>
Here's a Sample StackBlitz for your ref.
Upvotes: 3