Struggling to navigate through an Angular form to reach its controls

Introduction:

I am facing a challenge with nested angular forms that seems simple but is proving to be difficult. The dynamic creation of formGroups and formArrays within multiple components is causing confusion.

I apologize for the lengthy code snippet, but it's the minimal example I could provide to explain my issue clearly.


The parent component is quite straightforward with only two formControls. I pass the form to the tasks component to work with it.

Parent Component

this.intakeForm = this.fb.group({
   requestor: ['', Validators.required],
   requestJustification: ['', Validators.required]
});

HTML:

<form [formGroup]=“intakeForm”>

<app-tasks 
    [uiOptions]="uiOptions"
    [intakeForm]="intakeForm">
</app-tasks>

</form>

Tasks Component

A method in this component triggers generateTask which creates a new form group.

ngOnInit() {
    this.intakeForm.addControl('tasks', new FormArray([]));
}

// Push a new form group to our tasks array
generateTask(user, tool) {
    const control = <FormArray>this.intakeForm.controls['tasks'];
    control.push(this.newTaskControl(user, tool))
}

// Return a form group
newTaskControl(user, tool) {
    return this.fb.group({
      User: user,
      Tool: tool,
      Roles: this.fb.array([])
    })    
}

HTML:

<table class="table table-condensed smallText" *ngIf="intakeForm.controls['tasks'].length">
 <thead>
   <tr>
     <th>Role(s)</th>
   </tr>
 </thead>
 <tbody>
   <tr *ngFor="let t of intakeForm.get('tasks').controls let i = index; trackBy:trackByIndex" [taskTR]="t" [ui]="uiOptions" [intakeForm]="intakeForm" [taskIndex]="i">
   </tr>
 </tbody>
</table>

TR Component

A method in this component triggers the addRole method which adds the form group.

@Input('taskTR') row;
@Input('ui') ui;
@Input('intakeForm') intakeForm: FormGroup;

// Add a new role
addRole($event, task) {
   let t = task.get('Roles').controls as FormArray;
   t.push(this.newRoleControl($event))
}

// Return a form group
newRoleControl(role) {
   return this.fb.group({
     Role: [role, Validators.required],
     Action: [null, Validators.required]
   })
 }

HTML

<td class="col-md-9">
    <ng-select  [items]="ui.adminRoles.options" 
                bindLabel="RoleName" 
                bindValue="Role"
                placeholder="Select one or more roles" 
                [multiple]="true"
                [clearable]="false" 
                (add)="addRole($event, row)" 
                (remove)="removeRole($event, row)">
</td>

The Query

I'm struggling to add formControlName to my TR Component, specifically on the ng-select element. But when I attempt to do so, it says it needs to be within a formGroup.

As far as I can see, the formGroup is in the tasksComponent and wraps the whole table. So technically, it should be within a formGroup, right?

My ultimate goal is to add formControlName to this input, but I'm finding it challenging to figure out the correct path to achieve this.

Here is an image showing the full form object. The last expanded section, Role, is what this input should be named via formControlName for validation purposes.

https://i.sstatic.net/02U1B.png

Updates

Edit 1 - Changes made according to @Harry Ninh

Tasks Component HTML

<tbody>
  <tr *ngFor="let t of intakeForm.get('tasks').controls let i = index; trackBy:trackByIndex" [taskTR]="t" [ui]="uiOptions" [intakeForm]="intakeForm" [taskIndex]="i" [formGroup]="intakeForm"></tr>
</tbody>

TR Component HTML

<td class="col-md-9">
  <ng-select  [items]="ui.adminRoles.options" 
              bindLabel="RoleName" 
              bindValue="Role"
              placeholder="Select one or more roles" 
              [multiple]="true"
              [clearable]="false" 
              formControlName="Roles"
              (add)="addRole($event, row)" 
              (remove)="removeRole($event, row)">
</td>

Result:

ERROR Error: formControlName must be used with a parent formGroup directive.

Answer №1

It is necessary to specify [formGroup]="intakeForm" in the main tag of each component that contains any formControlName, formGroupName, or formArrayName elements. Angular will not automatically search up the structure to locate this information during compilation.

Answer №2

When working on a TR Component template, it is important to note that the root element (represented by <td>) must include the attribute [formGroup]="intakeForm". This informs Angular about the associated formControlName.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for installing TypeScript declarations for packages with scopes or namespaces using @types?

My current challenge involves the use of TypeScript and my desire to utilize a scoped package such as @foo/bar or @babel/core that does not include its own type declarations. My attempted solution so far has been to execute the following command: npm ins ...

What is the process for extracting a nested document from an array of documents in mongodb?

I am currently facing a challenge in my project where I need to remove a nested objects array within a document. The specific scenario involves searching for the days on which an event will be held, based on its event ID. const { eventid, typesOfTicketId ...

Why is Zod making every single one of my schema fields optional?

I am currently incorporating Zod into my Express, TypeScript, and Mongoose API project. However, I am facing type conflicts when attempting to validate user input against the user schema: Argument of type '{ firstName?: string; lastName?: string; pa ...

Every time I hit the refresh button, I receive dual responses

In my angular 6 application, there's a sidebar component sidebar.ts ngOnInit() { if (!Array.isArray(this.menu) || !this.menu.length) { const data = JSON.parse(localStorage.getItem('data')); this.item = data.response; ...

Extending IAngularStatic - navigating the challenges

Recently, I sought help with a question similar to this one and despite receiving assistance, I am still struggling with the code. In my typescript file, I have created a small service to work with the google api (referred to as gapi) along with an interf ...

The GoJS chart fails to refresh after the transaction has been finalized

I have integrated a GoJS diagram into my VueJs application. I am currently working on adding a search feature that highlights specific nodes with text matches. However, I encountered an issue where the diagram does not update immediately after triggering t ...

The function of the Nuxt.js server-side plugin is not functioning as intended

I recently developed a server-side plugin and encountered the following error: context.app.handleServerError is not a function // hanlde-server-error.js export default ({ app }, inject) => { app.handleServerError = (method, error, data) => { ...

Encountering a Typescript issue while implementing Next Auth V5 with the MongoDB adapter

I encountered a typescript error while trying to implement a MongoDB adapter in my Next Auth config. My goal is to utilize Next Auth for user authentication using MongoDB as the database. Currently, I am working with Next Auth V5. Below is a snippet from ...

The search form on my website is not functioning correctly as the input field is not taking any

My website can be found at I have noticed that the search field on my website does not allow input in Firefox version 17.01. Interestingly, the search function works perfectly fine on Chrome and Internet Explorer browsers. On my website's header, the ...

When attempting to upload a picture using the camera, the file upload process is unsuccessful

Whenever I attempt to upload an image from my existing files, everything goes smoothly. However, if I try to select a file by directly clicking on the camera icon on my mobile device, it fails with a "CORS Error" message. I have tried adding and removing t ...

Trigger a re-render of specific components upon clicking a button in React

Within my server file, there is a function that retrieves a specific set of data based on an ID. app.get('/musicbyid', function(req, res){ var query = req.query.term.toLowerCase(); music.find({ _id: query }, function(err, allMusic){ ...

There seems to be an issue with the proper loading of jQuery and JS functions onto

I'm trying to update my webpage dynamically using jQuery and JavaScript, but I am facing problems with loading the content. I have created 4 distinct objects and I want to display each object's content on the page by calling a function with speci ...

Javascript - Conceal a Dynamic Div Depending on its Text

I have a unique table that generates dynamic Divs with ID's that count as they are created in the following format: <div id="dgpCheckDiv10_0"> <input Delete </div> <div id="dgpCheckDiv10_1"> text2 </div> Some of t ...

Create a token for

Visit this link for more information on listing functions in Azure web apps https://i.sstatic.net/YgsF5.png Is there a way to dynamically generate the green-highlighted token using JavaScript or an API? While I'm aware that the token can be generate ...

Is there a way to send an array of arrays from JavaScript to PHP without using AJAX?

Is there a simple way to pass an array of arrays from JavaScript to PHP? An example of an array in JavaScript would be: var resultArray = [ {"id":"1", "description":"aaa", "name":"zzz", "titel":"mmm"}, {"id":"2", ...

The 'cookies' property is not defined in the 'undefined' type

I am working on incorporating Google's Sign-In for Cypress tests using the following plugin: https://github.com/lirantal/cypress-social-logins/ (I am utilizing TypeScript). The code I have implemented is as follows: it('Login through Google&apos ...

Challenges with loading content and async JavaScript within websites

I decided to replace the content on index.htm with the content from project.htm. By clicking on a#front, it redirects to project.htm and dynamically updates the content. However, I am facing an issue regarding how to run the javascript that accompanies thi ...

Sharing JSON data with public/javascripts/X.js in Node/Express: A beginner's guide

Currently facing a challenge with my Express project. Take a look at https://github.com/MoreeZ/help1 and examine ./public/javascripts/budget.js. My goal is to swap the incomeData object to read data from ./incomedata.json I attempted passing it through th ...

Guidelines for sending JSON Data via Request Body using jQuery

I'm not well-versed in jQuery, so consider me a beginner. Here's my code that is not correctly handling JSON data submission via Request Body. <!doctype html> <html lang="en> <head> <title>jQuery JSON Data Submission ...

The debate between client-side and server-side video encoding

My knowledge on this topic is quite limited and my Google search didn't provide any clear answers. While reading through this article, the author mentions: In most video workflows, there is usually a transcoding server or serverless cloud function ...