The parent component is failing to pass the form values to the child form group in CVA

My Angular application (view source code on Stackblitz) is running Angular 15, and it utilizes reactive forms along with a ControlValueAccessor pattern to construct a parent form containing child form groups. However, I am encountering an issue where the data is not being passed to the child when I designate it as a FormGroup in the parent's HTML template. On the other hand, if I label it as a FormControl, the data passes correctly and the child form can access it, but this approach results in an error:

ERROR Error: control.registerOnChange is not a function

Additionally, when annotating it as a FormControl, I am unable to retrieve the individual controls within the FormGroup.

In the provided code example, childGroupForm2 successfully receives the passed values, while childGroupForm does not.

My ideal solution would be to specify the FormGroup as a FormGroup and successfully pass the values from the parent component to the child.

Does anyone have insights into why this method is unsuccessful with FormGroups yet functional with FormControls?

Below is an updated version of the code for brevity:

// parent.component.html

<form [formGroup]="parentForm">
   <child-group [formGroup]="childGroupForm"> </child-group>
   <child-group [formControl]="childGroupForm2"> </child-group>
</form>  



// parent.component.ts

get childGroupForm(): FormGroup {
    return this.parentForm.get('childGroupForm') as FormGroup;
}

get childGroupForm2(): FormControl {
    return this.parentForm.get('childGroupForm2') as FormControl;
}

ngOnInit() {
    this.parentForm = this.fb.group({
      childGroupForm: this.fb.group({
        elementInput: 'Test1',
        elementsSelectionInput: 'Test2',
      }),
      childGroupForm2: this.fb.group({
        elementInput: 'Test3',
        elementsSelectionInput: 'Test4',
      }),
    });
}

Answer №1

A custom form control for your child-group is necessary, which is essentially a component that implements ControlValueAccessor. This custom form control is associated with a FormControl, not a FormGroup.

Therefore, in the parent component, your form should be structured as follows:

this.parentForm = this.fb.group({
  name: 'Test0',
  childGroupForm: this.fb.control({ 
    elementInput: 'Test1',
    elementsSelectionInput: 'Test2',
  }),
  childGroupForm2: this.fb.control({ 
    elementInput: 'Test3',
    elementsSelectionInput: 'Test4',
  }),
}); 

Your parent component template should look like this:

<form [formGroup]="parentForm">
  <child-group formControlName="childGroupForm"></child-group>
  <child-group formControlName="childGroupForm2"></child-group>
</form>

In my personal opinion, a custom form control should be utilized when managing a series of inputs or when more complexity is required. However, you can achieve similar results using a simple component with viewProvider as demonstrated here.

For an example utilizing a formGroup, please refer to the sample on StackBlitz.

//child
@Component({
  selector: 'hello',
  template: `<h1>Hello </h1>
  <div [formGroupName]="group">
    <input formControlName="elementInput"/>
    <input formControlName="elementsSelectionInput"/>
  </div>      `,
  styles: [`h1 { font-family: Lato; }`],
  viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class HelloComponent  {
  @Input() group: string;
  
  constructor(){}
}

Then utilize the parent component like so:

  <form [formGroup]="form">
     <hello [group]="'childGroupForm'"  > </hello>
  </form>

  form=new FormGroup({
    childGroupForm:new FormGroup({
      elementInput:new FormControl(),
      elementsSelectionInput:new FormControl()
  
    })
  })

NOTE: In the provided example, new Form and new FormGroup are used instead of formBuilder, but the concept remains the same.

Answer №2

When setting up the form in your parent component, make sure to pass 'form' instead of 'group' to the childGroupForm:

ngOnInit() {
    this.parentForm = this.fb.group({
      name: 'Test0',
      childGroupForm: this.fb.form({ //update this.fb.group to this.fb.form
        elementInput: 'Test1',
        elementsSelectionInput: 'Test2',
      }),
      childGroupForm2: this.fb.form({ //update this.fb.group to this.fb.form
        elementInput: 'Test3',
        elementsSelectionInput: 'Test4',
      }),
    });
  }

Happy coding!

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

Error: An identifier was unexpectedly encountered while using the Submit Handler

I am currently working on creating a validation script and an AJAX call. I have encountered a problem where the alert message is not working within the if condition. I can't seem to figure out what's causing this issue. When I execute the scri ...

ToggleClass is not being applied to every single div

I am currently designing a pricing table with hover effects. You can view the progress here: Upon hovering on a pricing table, all the divs are toggling classes which is not the desired behavior. I want each element to have its own separate interaction. ...

Best practices for transmitting the User Id in Ionic 4: Opt for Storage or utilize Routing to Send User ID

In my ongoing project with Ionic 4, I find myself in a dilemma regarding how to handle the User ID. The scenario is this: upon user login, the application receives the User ID and then redirects to a specific route. I am uncertain whether it would be more ...

The "variable" used in the React app is not defined, resulting in a no

Following the tutorial of Mosh Hamedani, I attempted to create a react-app. You can watch the tutorial here. I followed his instructions exactly as mentioned. I encountered an issue when trying to pass an argument named product to a function called on on ...

Utilize Node.js v16 for the execution of chaincode operations

Currently, I am executing JavaScript/TypeScript chaincode from fabric-samples (asset-transfer-basic/chaincode-javascript) and my requirement is to switch the Node.js version from 12 to 16. I suspect that the hyperledger/fabric-nodeenv image is specifying ...

Using Javascript to dynamically populate dropdown options based on radio button selection

I am in the process of developing a basic form that allows users to input the frequency of a specific report. Initially, users were only able to enter days of the week. However, due to changes in demand for certain reports, options such as workday and day ...

Typescript error message TS2314: One type argument is required for the generic type 'Array<T>'

I recently started my journey in learning typescript and have written some basic code. class Learning { subjects: Array[string]; hoursPerDay: number; constructor(subj: Array[string], hrs: number) { this.subjects = subj; thi ...

JavaScript code to generate a UTF8 string from UTF codes

I am in possession of the byte representation of UTF8, such as: 195, 156 for "Ü" (capital U Umlaut) I am struggling to generate a JavaScript-compatible string from these numbers - all my attempts have been unsuccessful. Every method I have tried has mis ...

Unable to close expanded grid item using close button

Currently, I am working on a simple 3 column grid where each grid item consists of an image and a close button. The functionality I want to achieve is that when a grid item is clicked, the image should expand and the close button should become visible. Th ...

The method .makePerspective() in THREE.Matrix4 has been updated with a new signature. Make sure to refer to the documentation for more information

Attempting to run a functional three.js code using release 119 of three.js (instead of r79) has resulted in an error being thrown by the previously functioning code: THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check ...

The Shopify storefront API's create cart mutation generates an HTML response when called

I recently started developing an e-commerce website using Next.js and Shopify's storefront API. I have successfully set up the connection and can list all the products from the API. However, I encountered an issue when attempting to add a product for ...

Is there a simple method to automatically increase the version number of Mongoose documents with each update request?

I'm eager to utilize Mongooses document versioning feature with the "__v" key. Initially, I struggled with incrementing the version value until I learned that adding this.increment() when executing a query is necessary. Is there a method to have this ...

What is the best method to extract and manipulate data from a JSON file in an AngularJS application?

personManagerInstance.getString("firstname",'common','en') I am currently passing a direct string in the UI which is affecting it. What I actually need is to read the data from a JSON file and return it as a string. personManagerInstan ...

What is the process for importing a jquery plugin like turnjs into a React component?

After searching through countless posts on stackoverflow, it seems like there is no solution to my problem yet. So... I would like to integrate the following: into my react COMPONENT. -I attempted using the script tag in the html file, but react does no ...

Utilize Angular2's input type number without the option for decimal values

Is there a way to prevent decimals from being entered in number inputs for Angular 2? Instead of using patterns or constraints that only invalidate the field but still allow typing, what is the proper approach? Would manually checking keystrokes with the ...

Steps for extracting a specific portion of a value contained within an attribute

In my code, there are multiple hyperlinks with different values attached to an onclick function. Here is an example: <a onclick="Utils.decideOffer('', {'unlockFeature': 'cars'});">cars text</a> <a onclick="Util ...

Guide on converting JSON to CSV in React by utilizing the map function

When I convert JSON data to CSV by clicking a button, it currently stores the data in the CSV file separated by commas. However, I want each piece of data to be on its own line. How can I achieve this? For example: Minor,Minor What I Want: Each item on a ...

Guide on transforming an Angular 6 project into a Progressive Web Application (PWA)

Currently, my Angular 6 project is up and running smoothly. However, I am looking to integrate PWA into my existing application. When I execute the following command: ng add @angular/pwa The output displays: + @angular/<a href="/cdn-cgi/l/email-protec ...

The link in the drop down select is not functioning in IE8/9. When trying to open the drop down select link, an

Could use some help with IE8 and 9 compatibility, can't seem to find a solution. This code works smoothly on Chrome, FF, and Safari. There are two dropdown menus, each with two links. Every dropdown menu has its own "Buy Now" button. Upon selecting ...

Having trouble importing Material UI and working with ClickAwayListener

For my current project, I am utilizing material-ui to implement the functionality for changing passwords. In this root file, I am importing several child components: Personalize.js import React, { useContext, useState } from 'react'; import Cook ...