Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to add a custom component to a reactive form's FormGroup?

I am having a lot of problems using formControlName on a custom component wrapping an mat-select.

Now it appears that my custom control cannot find the form group? Even though the custom element is nested under the formGroup.

I have a StackBlitz

But the problem comes in when I nest my custom component under the formGroup, all of the other controls can find the formGroup but my custom component doesn't seem to be able to.

<form novalidate [formGroup]="tenantForm">
    <label for="Id">Id</label>: <input class="form-control" formControlName="id" id="Id" name="Id" />
    <custom-component-with-mat-select formControlName="culture" id="Culture" name="Culture"></custom-component-with-mat-select>
</form>

In this example the Id field would work properly, but the Culture field complains about not being nested in a FormGroup?

Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).

How should a custom component work with reactive forms and form group?

My original problem was not remembering to import the ReactiveFormsModule.. Maybe I'm forgetting to import something again?

Is this answer the designed way to accomplish this? Or am I missing a simplier solution??

Do I need to implement a control value accessor?? As explained here

just confused on the designed way to do this.

my component wraps angular material's mat-select, and I guess I'm also confused if I need to put attributes on the mat-select or have my component implement the control value accessor? nothing seems to be working.

like image 821
JBoothUA Avatar asked Oct 17 '22 11:10

JBoothUA


2 Answers

I solved that problem using the parameter 'formControl' instead of 'formControlName' like this: input-date.compoenent.html

<p-calendar [formControl]="control"></p-calendar>

parent.component.html

<input-date [control]="formGroup.controls.date"></input-date>

Where control is an input of input-date.component:

@Input() control: FormControl;
like image 118
Moisés Palma Isern Avatar answered Oct 28 '22 22:10

Moisés Palma Isern


Control formControlName must be string value.

Case 1

formControlName="animationType"

This working since animtationType is string value here.

Case 2

[formControlName]="'animationType'" 

This is throwing error since Angular is evaluating the value of animationType which is an array (defined in ts file)

Case 3

formControlName="{{animationType}}" 

This is failing as same reason as case 2

Fix

If you want to access the formControlName then use string value in ts ex :

** in ts **

public animationControl = "animation";

** in html **

<mat-select name="animationType" [formControlName]="'animationControl'" 
like image 35
Sunil Singh Avatar answered Oct 28 '22 22:10

Sunil Singh