Reputation: 48
I am attempting to dynamically present users a set of questions for every product selected.
I have created the questions FormGroup, and then I iterate through the selected products and nest the group of questions beneath each product.
To a degree, this seems to work. The form is created, I can see it via the JSON pipe, and can interact with it.
The problem, however, is that all of the form controls for each product only update the controls for the last product (which I can see via {{form.value | JSON}}
Sample Code:
https://stackblitz.com/edit/angular-py4sam
app.component.ts
import { Component, NgModule, VERSION, OnInit } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormControl, FormGroup, FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
questionsForm: FormGroup;
qaForm: FormGroup;
questions = [
{
'question': 'like?',
'value': ''
},
{
'question': 'own?',
'value': ''
}
]
products = [
{
'make': 'fender'
},
{
'make': 'gibson'
}
]
createQuestionsForm() {
this.questionsForm = new FormGroup({
questions: new FormArray([])
});
const qArray = <FormArray>this.questionsForm.controls['questions'];
this.questions.forEach((item, index) => {
const aGroup = new FormGroup({
answer: new FormControl(item.question),
value: new FormControl(item.value)
})
qArray.push(aGroup);
})
}
ngOnInit() {
this.createQuestionsForm();
this.qaForm = new FormGroup(
{
qa: new FormArray([])
});
const qaFormArray = <FormArray>this.qaForm.controls['qa'];
this.products.forEach((item, index) => {
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.questionsForm
})
qaFormArray.push(fg);
})
}
}
app.component.html
<h3>FORM</h3>
<form [formGroup]="qaForm">
<div formArrayName='qa'>
<div *ngFor="let prod of products; let productCount = index">
<h3>{{ prod.make }}</h3>
<div [formArrayName]=productCount>
<div formGroupName="form">
<div formArrayName="questions">
<div *ngFor="let q of questions; let qCount = index">
<div [formArrayName]=qCount>
<input type="checkbox" formControlName="value"> {{ q.question }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<p>qaform {{ qaForm.value | json }}</p>
Upvotes: 1
Views: 530
Reputation: 214315
The issue here is that you use the same questionsForm
for all products:
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.questionsForm
^^^^^^^^^^^^^^^
})
In order to fix it you need to create questionsForm
per product.
Here is how it could be accomplish:
createQuestionsForm() {
const questionsForm = new FormGroup({
questions: new FormArray([])
});
const qArray = <FormArray>questionsForm.controls['questions'];
this.questions.forEach((item, index) => {
const aGroup = new FormGroup({
answer: new FormControl(item.question),
value: new FormControl(item.value)
})
qArray.push(aGroup);
})
return questionsForm;
}
...
this.products.forEach(
...
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.createQuestionsForm()
})
Upvotes: 1