Reputation: 2101
I have a Form Array that I would like to duplicate for each iteration of an *ngFor
loop. My form is setup in the model as follows:
initProducts() {
return this.fb.group({
begTally: ['', Validators.required],
endTally: ['', Validators.required],
})
}
ngOnInit() {
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts()
])
})
}
When I print out the form in the view with {{ myform.value | json }}
I am only seeing one iteration of the form array. Here's a StackBlitz with the full setup. I would also like to patch in the values to the form controls from my prodData json. Not sure what I'm doing wrong.
Upvotes: 1
Views: 9076
Reputation: 23793
Within your Stackblitz example you were not that far!
Here's my proposal:
this.productionForm = this.fb.group({
production: this.fb.array(
this.prodData
// for each...
.groups
.reduce((acc, group) => [
...acc,
// ...product of each group
...group.products.map(product =>
// create a form group
this.fb.group({
begTally: [product.begTally, Validators.required],
endTally: [product.endTally, Validators.required],
})
)
], [])
)
})
production
)reduce
, which allows you to then loop on every products from every groupsIn the view, it's a little bit more tricky as you want to access data that are not stored into the form. So we have to mix between original data and the ones within our form:
<form [formGroup]="productionForm">
<table *ngFor="let group of prodData.groups; let i = index">
<thead>
<th class="group-name">
<span>{{group.name}}</span>
</th>
<th>Beginning Tally</th>
<th>Ending Tally</th>
<th>Total</th>
</thead>
<tbody formArrayName="production">
<tr *ngFor="let product of group.products; let j=index" [formGroupName]="i + j">
<td>{{product.name}}</td>
<td>
<input type="number" formControlName="begTally">
</td>
<td>
<input type="number" formControlName="endTally">
</td>
<td>
{{ product.begTally + product.endTally }}
</td>
</tr>
</tbody>
</table>
</form>
Here's my fork of your Stackblitz with a working example:
https://stackblitz.com/edit/angular-kvlxnp?file=src%2Fapp%2Fapp.component.ts
Upvotes: 2
Reputation: 32507
You must have the same number of groups in form as in markup. For example
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts(),
this.initProducts(),
this.initProducts()
])
})
will fix the issue, which means you have to interate the same collection that *ngFor
iterates, and create the same ammount of FormControls
Upvotes: 0