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],
})
)
], [])
)
})
- to create a form array, you need to wrap it into a form group (here called
production
)
- then loop on the groups using
reduce
, which allows you to then loop on every products from every groups
- build a form group for each of them
In 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