I'm having a hard time integrating this form with the html. can you help me? I've tried in some ways but I couldn't connect because I'm using FormArray. I made the form but to access the controls in the html is very complicated. I need it to be form Array, because this will have several arrays with categories. I need it to be form Array, because this will have several arrays with categories.
Form in Component TS
testeForm: FormGroup = this.fb.group({
feedstock: this.fb.array([
this.addFeedStockArray()
])
});
addFeedStockArray(): FormGroup {
return this.fb.group({
category: "",
position: "",
feedstockOptions: this.fb.array([
this.addFeedStockOptions()
]),
})
}
addFeedStockOptions(): FormGroup {
return this.fb.group({
name: '',
code: '',
price: {
amount: '',
currency: ['BRL'],
}
})
}
addfeedStockClick(): void {
(<FormArray>this.testeForm.get('feedstock')).push(this.addFeedStockOptions());
}
<div [formGroup]="testeForm" style="margin-left: 40px">
<div class="second-column row" formArrayName="feedstock" >
<div class="row" [formGroupName]="i" *ngFor="let feedstock of feedstock.get('feedstockOptions')?.controls; let i = index">
<div class="form-group col">
<label>
NOME:
</label>
<input class="form-control"
placeholder="--" formControlName="name" >
</div>
<div class="form-group col">
<label>
CÓDIGO:
</label>
<input class="form-control"
placeholder="--" formControlName="code">
</div>
<div class="form-group col">
<label>
PREÇO:
</label>
<input class="form-control"
currencyMask
[options]="{ prefix: 'R$ ', thousands: '.', decimal: ',', align:'left'}"
min="0"
placeholder="R$" formControlName="price" >
</div>
<div class="form-group col">
<i class="material-icons close-category" style="margin-top: 40px" (click)="removefeedStockClick(i)" >
close
</i>
</div>
</div>
</div>
</div>
I would suggest a minimal change to see if it fixes your issue
<div [formGroup]="testeForm" style="margin-left: 40px">
<div class="second-column row" formArrayName="feedstock" >
<ng-container *ngFor="let feedstock of feedstock.get('feedstockOptions')?.controls; let i = index">
<div class="row" [formGroupName]="i">
<div class="form-group col">
<label>NOME:</label>
<input class="form-control" placeholder="--" formControlName="name" >
</div>
</div>
......
</ng-container>
Used an ng-container to wrap the *ngFor directive
UPDATE
After seeing the complete code, realized there is one larger mistake: There are 2 levels of FormArray and need to be accessed like that.
<div [formGroup]="testeForm" style="margin-left: 40px">
<div class="second-column row" formArrayName="feedstock" >
<ng-container *ngFor="let fcFeedStock of testeForm.get('feedstock')?.controls; let i = index">
<ng-container [formGroupName]="i">
<ng-container formArrayName="feedstockOptions">
<ng-container *ngFor="let feedstockOption of fcFeedStock.get('feedstockOptions')?.controls; let j = index">
<div class="row" [formGroupName]="j">
<div class="form-group col">
<label>NOME:</label>
<input class="form-control" placeholder="--" formControlName="name" >
</div>
</div>
......
</ng-container>
</ng-container>
</ng-container>
</div>
UPDATE 2:
Showing price > amount
As price is a FormGroup, and amount is a FormControl:
...
<div class="row" [formGroupName]="i">
<div class="form-group col">
<label>NOME:</label>
<input class="form-control" placeholder="--" formControlName="name" >
</div>
<div formGroupName="price">
<input formControlName="amount">
</div>
</div>
...
How to add one new element to the array:
The issue is you are confusing between the 2 FormArrays 'feedstock' and 'feedstockOptions'.
// This function should do feedstock.push(this.addFeedStockArray())
addfeedStockClick(): void {
(<FormArray>this.testForm.get('feedstock')).push(this.addFeedStockArray());
}
For adding to feedstockOptions, you first need the index of the feedstock, access it's feedstockOptions, and then push to it:
(<FormArray>(<FormArray>this.testForm.get('feedstock')).at(index).get('feedstockOptions')).push(this.addFeedStockOptions());
or if you can manage to directly access the fcFeedstock, the line of code would simplify to:
(<FormArray>fcFeedstock.get('feedstockOptions')).push(this.addFeedStockOptions())