I am fairly new to Angular and am trying to build a fairly complex form for a food delivery system I have been building.
I am currently building a form which would enable me to add a menu item to a restaurants menu.
I have built an angular form to do this, part of the form includes a section for addons, this would relate to things like sauces, flavors etc. The data is structured in such a way that there is an addons array that contains addon objects containing and addon type as well as an array of options relating to that type.
I have built a method to create a new addon in my addons array with two inputs, one for the name being a standard control taking a string and the other being an array nested in this object that includes all the addon options relating to that type.
I am able to add a new addon as well as addon options within that addon object but when trying to update values of those nested options I am unable to attach a formControlName to each of thos options which I need in order to update their values.
I keep getting the below error for reference
vendor.js:63956 ERROR Error: Cannot find control with path: 'addons -> 0 -> 0 -> option
when creating the new option I'm not sure how to give it a unique formcontrol name so that its value can be updated. Any input would be massively appreciated.
Below is my code
TS.
Main Form
menuForm = this.builder.group({
name: this.builder.control<string>('', Validators.required),
price: this.builder.control<string>('', Validators.required),
description: this.builder.control<string>('', Validators.required),
itemType: this.builder.control<string>('', Validators.required),
image: this.builder.control<NonNullable<any>>('', Validators.required),
imageName: this.builder.control<string>('', Validators.required),
categories: this.builder.array([]),
relatedsides: this.builder.array([]),
addons: this.builder.array([]),
});
Methods for adding new addon and adding a new addon option
addAddon() {
const addOnForm = this.builder.group({
addonname: ['', Validators.required],
addonoptions: this.builder.array([]),
});
this.addons.push(addOnForm);
}
addAddonOption(i: number) {
const addOnOptionForm = this.builder.group({
option: this.builder.control<string>(''),
});
this.addons.value[i].addonoptions.push(addOnOptionForm);
console.log('addons with options', this.addons.value);
}
HTML:
<!-- Addons Array -->
<ng-container type="form" formArrayName="addons">
<h4>Add Addons</h4>
<ng-container *ngFor="let addOnForm of addons.controls; let x = index">
<div [formGroupName]="x" >
<mat-form-field appearance="fill">
<input matInput placeholder="Addon" formControlName="addonname" />
</mat-form-field>
<button type="button" (click)="deleteAddOn(x)">Delete Addon</button>
<button type="button" (click)="addAddonOption(x)">
add addon option
</button>
<ng-container
*ngFor="
let addonoption of addons.value[x].addonoptions;
let k = index
"
>
<div [formGroupName]="k" >
<mat-form-field appearance="fill">
<input
matInput
type="text"
placeholder="Add On Option"
formControlName="option"
/>
</mat-form-field>
</div>
</ng-container>
</div>
</ng-container>
</ng-container>
<div>
<button type="button" (click)="addAddon()">Add Addon</button>
</div>
CodePudding user response:
Your structure of FormGroup
from the root form to option
control should be:
Root FormGroup
--> addons
FormArray
--> index of addon FormGroup
--> addonoptions
FormArray
--> index of addonoption FormGroup
--> option
FormControl
Miss out
formArrayName="addonoptions"
for the template.Modify the way to iterate the
addonoptions
FormArray
fromaddon
FormGroup
.
<ng-container formArrayName="addonoptions">
<ng-container
*ngFor="
let addonoption of addonoptions(x).controls;
let k = index
"
>
<div [formGroupName]="k" >
<mat-form-field appearance="fill">
<input
matInput
type="text"
placeholder="Add On Option"
formControlName="option"
/>
</mat-form-field>
</div>
</ng-container>
</ng-container>
addAddonOption(i: number) {
const addOnOptionForm = this.builder.group({
option: this.builder.control<string>(''),
});
this.addonoptions(i).push(addOnOptionForm);
console.log('addons with options', this.addons.value);
}
addonoptions(addonFormIndex: number): FormArray {
return (this.addons.get(`${addonFormIndex}`) as FormGroup).controls
.addonoptions as FormArray;
}