I am building a nested, dynamic Form where the User has a group, and then can nest conditions within that group, or new additional group objects within a group
FormArray. Here is what the basic UI looks like. Note, not all the pieces are working, but for now I am trying to add a nested group. A nested group will work for the FormBuilder
, but it gives an error and does not show correctly on the UI. The error is: ERROR Error: Cannot find control with path: 'statement -> groups -> 0 -> groups -> conditions'
. Before going further, the StackBlitz can be found HERE
The form object looks like this:
{
"statement": {
"groups": [
{
"conjunctor": null,
"conditions": [
{
"variable": ""
}
],
"groups": []
}
]
}
}
Within the statement → groups → groups
the user is able to push an additional FormGroup
that will contain a "groups" object:
{
"conjunctor": null,
"conditions": [
{
"variable": ""
}
],
"groups": []
}
Long term, I expect to be able to push additional groups and further nest this Form, but for now, I am trying to get it to work on the UI. The HTML is as shown below and in this StackBlitz. I continue to get the error:
ERROR Error: Cannot find control with path: 'statement -> groups -> 0 -> groups -> conditions'
, and based off several S.O. examples, I recognize that this error is due to the way my HTML is nested and the FormGroups and FormArrays, there must be an issue within it. However, I cannot seem to get it to work in order to nest and display a nested group.
Here are some approaches I have tried:
Angular FormArray: Cannot find control with path
Angular: Cannot find control with path: 'variable-> 0 -> id'
Angular 7 and form arrays error of cannot find a control with path
ERROR Error: Cannot find control with path
As a side-note, I'm not sure if this is even the best approach to implementing a nested reusable component, but I expect to research this further once I stop getting errors.
<form [formGroup]="form">
<div formArrayName="statement">
<div formArrayName="groups">
<div *ngFor="let group of form.get('statement.groups')['controls']; let i = index">
<fieldset>
<legend>Group {{ i + 1 }}:</legend>
<div [formGroupName]="i">
<span style="float: right;">
<button type="button" style="float: right; cursor: pointer; margin-left: 5px;" (click)="deleteGroup(i)">
delete group
</button>
<button type="button" style="cursor: pointer; margin-left: 5px;" (click)="addNestedGroup(i)">
add nested group
</button>
<button
type="button"
style="cursor: pointer; margin-left: 5px;"
(click)="addNewCondition(group.controls.conditions)"
>
add condition
</button>
</span>
<div formArrayName="conditions">
<div *ngFor="let condition of group.get('conditions')['controls']; let j = index">
<fieldset>
<legend>Condition {{ j + 1 }}</legend>
<div [formGroupName]="j">
<input style="vertical-align: middle;" type="text" formControlName="variable" />
<button
style="float: right; margin-bottom: 5px;"
(click)="deleteCondition(group.controls.conditions, j)"
>
delete condition
</button>
</div>
</fieldset>
</div>
</div>
<ng-container>
<div formArrayName="groups">
<div *ngFor="let num of group.get('groups').value; let idx = index">
<fieldset>
<legend>Group {{ 2 }}:</legend>
<span style="float: right;">
<button
type="button"
style="float: right; cursor: pointer; margin-left: 5px;"
(click)="deleteGroup(0)"
>
delete group
</button>
<button type="button" style="cursor: pointer; margin-left: 5px;" (click)="addNestedGroup(0)">
add nested group
</button>
<button
type="button"
style="cursor: pointer; margin-left: 5px;"
(click)="addNewCondition(num.conditions)"
>
add condition
</button>
</span>
<div formArrayName="conditions">
<div *ngFor="cond; of: group.controls; let k = index">
<fieldset>
<legend>Condition {{ k + 1 }}</legend>
<div [formGroupName]="k">
<input style="vertical-align: middle;" type="text" formControlName="variable" />
<button
style="float: right; margin-bottom: 5px;"
(click)="deleteCondition(group.controls.conditions, k)"
>
delete condition
</button>
</div>
</fieldset>
</div>
</div>
</fieldset>
</div>
</div>
</ng-container>
</div>
</fieldset>
</div>
</div>
</div>
</form>