Angular Error: Cannot find control with path 'instructions -> 1 ->action'

Mytho

I'm trying to build a form. This form has the below structure. My users need to be able to create any amount of entries for the instruction fields.

...
  this.buttonForm = this.fb.group({
    instructions: this.fb.array([
        this.fb.group({
            action: this.fb.control('', Validators.required),
            data: this.fb.group({
                message: this.fb.control(""),
                mediaName: this.fb.control(""),
                mediaType: this.fb.control(""),
                commandName: this.fb.control(""),
                commandTrigger: this.fb.control("")
            })
        })
    ]),
    name: this.fb.control("", Validators.required),
    dimensions: this.fb.group({
        width: this.fb.control(5, [Validators.required, Validators.min(1)]),
        height: this.fb.control(5, [Validators.required, Validators.min(1)]),
        positionX: this.fb.control(5, [Validators.required, Validators.min(0)]),
        positionY: this.fb.control(5, [Validators.required, Validators.min(0)])
    })
});

}

...

get instructionAray() {
    return this.buttonForm.get("instructions") as FormArray;
}

public addInstruction() {
    this.instructionAray.push(this.fb.control(""));
}

Below is the HTML for the component (excluding the non array items).

<ng-container formArrayName="instructions">
            <ng-container *ngFor="let instruction of instructionAray.controls; let i = index" [formGroupName]="i">
                <div class="flex flex-col gap-4 border border-solid border-red-300 p-2">
                    <select #action  formControlName="action" class="formBackground"
                        (change)="resetInstruction(i, $event.target)">
                        <option value="Command">Command</option>
                        <option value="Media">Media</option>
                        <option value="Message">Message</option>
                    </select>
                    <div *ngIf="action.value == 'Message'" >
                        <div class="flex flex-row gap-x-2" formGroupName="data">
                            <p>Message:</p>
                            <input type="text" formControlName="message" class="formBackground ml-2">
                        </div>
                    </div>
                    <div *ngIf="action.value == 'Media'" formGroupName="data">
                        <div class="flex flex-row gap-x-2">
                            <p>Media:</p>
                            <input type="text" formControlName="mediaName" class="formBackground ml-2">

                        </div>
                        <div class="flex flex-row gap-x-2 mt-2">
                            <p>Type:</p>
                            <select formControlName="mediaType" class="formBackground ml-2">
                                <option value="soundEffect">Sound Effect</option>
                                <option value="imageGif">Image / GIF / Static</option>
                                <option value="video">Video</option>
                            </select>
                        </div>
                    </div>
                    <div *ngIf="action.value == 'Command'" formGroupName='data'>
                        <div class="flex flex-row mt-2 gap-x-2">
                            <p>Name:</p>
                            <input type="text" formControlName="commandName" class="formBackground ml-2">
                        </div>

                        <div class="flex flex-row mt-2 gap-x-2">
                            <p>Trigger:</p>
                            <select formControlName="commandTrigger" class="formBackground ml-2">
                                <option selected value="Manual">Manual (Default, only option)</option>
                            </select>
                        </div>
                    </div>

                    <button (click)="delete(i)" class="bg-red-500 text-white rounded-xl self-center p-2">Delete Instruction</button>
                </div>
            </ng-container>
        </ng-container>

        <button (click)="addInstruction()" class="bg-blue-500 text-white rounded-xl self-center p-2 mt-1">
            Add Instruction</button>

I'm running into a problem when I try to display the form array data. The first item in the array with the defualt properties displays fine. However, when I add another item to the form array it fails with the below error.

ERROR Error: Cannot find control with path: 'instructions -> 1 -> action'
    Angular 11
    ButtonFormComponent_ng_container_40_Template button-form.component.html:68
    Angular 26
    RxJS 6
    Angular 23
    ButtonFormComponent_Template button-form.component.html:108
    Angular 12
    BoardComponent_ng_template_3_Template board.component.html:43
    Angular 8
    openTemplateSheetMenu board.component.ts:52
    BoardComponent_div_2_Template__svg_svg_click_1_listener board.component.html:23
    Angular 24
    BoardComponent_div_2_Template board.component.html:23
    Angular 9
    BoardComponent_Template board.component.html:20
    Angular 2
core.mjs:6412:22

I've been stuck on this for a few days now with no success.

onrails

Translating this error to plain English;

You are creating a formArray and you are supplying a default object formGroup to it OnInit. At this point of time you created a formGroup by default inside your formArray. So in your array you have an object at index 0. Thus, when you press the addInstruction() you are pushing a new object to the array. Meaning an object at index 1. That's why the compiler complains about the absence of a control named action at index 1 when you push the new object by pressing addInstruction(). In the supplied code above, the addInstruction() does not create a new object that includes the shape of the object you set by default at index 0. It only pushes an abstract formControl to the formArray.

So you need to refactor as follows:

1- Declare a property in your class of type FormArray named instructions

public instructions: FormArray

2- Rework the addInstruction():

addInstruction() {
    this.instructions = this.buttonForm.get("instructions") as FormArray;
    this.instructions.push(this.createInstructions());
}

3- add a new method named createInstructions()

createInstructions(){
   return this.fb.group({
           action: this.fb.control('', Validators.required),
            data: this.fb.group({
                message: this.fb.control(""),
                mediaName: this.fb.control(""),
                mediaType: this.fb.control(""),
                commandName: this.fb.control(""),
                commandTrigger: this.fb.control("")
            })
})}

4- Remove the get instructionAray()

It is not recommended to call methods that way in your template. For performance reasons use direct properties. Knowing that you have the buttonForm already in your HTML you can access your formArray in the *ngFor as follows:

this.buttonForm.get('instructions')['controls']

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Angular 2 Form "Cannot find control with path"

Angular 2 Reactive Forms: Cannot find control with path

Angular material stepper: Error: Cannot find control with name: 'formArray'

Angular 4 Error: Cannot find control with unspecified name attribute

Angular2: Cannot find form control at index 1 at FormArray

Angular 5 FormArray > Cannot find control with path: 'fields -> 0 -> name'

ERROR Error: Cannot find control with path

Angular FormArray: Cannot find control with path

Angular Reactive Forms: Cannot find control with path:

Angular: Cannot find control with path: 'variable-> 0 -> id'

Error: Cannot find control with path: 'x ' angular 2

angular 4: nested form fields : Cannot find control with path

Angular 7 and form arrays error of cannot find a control with path

Cannot find control with path: 'marketplace -> 1 -> marketplace'

Angular 8 and form arrays error cannot find control with path: index

Cannot Find Control with Path Using ngIf on Recursive Angular Form

Nested Form Array Woes: ERROR Error: Cannot find control with path: 'questions -> 0 -> code'

Angular 6 Forms Cannot find control error

"Cannot find control with path" but cannot figure out why - Angular 5

Angular Form Array Cannot find control with path

Get the following error : Error: Cannot find control with path: 'budgetIncomes -> 0 -> '

Angular Error As Cannot find control with path: '_OSkilss -> 0 -> Imageuploade'

ERROR Error: Cannot find control with path: Angular FormArray

Error: Cannot find control with path: 'specs -> 2' FormArray checkbox list

ERROR Error: Cannot find control with path: 'flights -> 3'

Cannot find control with path: 'data -> 1 -> value'

Angular formArray Cannot find control with path

Get error: Cannot find control with path: 'excludedPeriods -> 0 -> dateTo'

Angular ngFor in ngFor formControlName : Cannot find control with path