0

So I have an (Angular 10) reactive form with a number of input components like this one, each created dynamically in an ngFor loop:

<div [id]="this.getDivElementId()" class="textinput dynControl" [formGroup]="this.parentFormRef" > <input [name]="this.controlData.name" [id]="this.controlData.name" type="text" [attr.aria-labelledby]="this.getLabelElementId()" [attr.aria-required]="this.controlData.required" [required]="this.controlData.required" [readOnly]="this.controlData.readOnly" (input)="onValueChange($event)" [maxlength]="this.controlData.maxLength" [placeholder]="this.controlData.placeholder" [pTooltip]="this.controlData.tooltip" pInputText [formControlName]="this.controlData.name"> <label [for]="this.getLabelElementId()" [id]="this.getLabelElementId()" [attr.data-required]="this.controlData.required">{{this.label}}</label> </div> <div class="validationFeedback"> <small *ngIf="this.controlRef?.errors?.required && (this.controlRef?.touched || this.controlRef?.dirty)" class="ng-invalid p-invalid"> {{this.getRequiredFieldValidationMsg()}} </small> </div> 

I have a weird situation in which some of the component instances (but not all) are getting marked as ng-invalid even when the FormControl's error property is empty. There is valid input in the control, and the validation section stays hidden, but the control itself is marked with ng-invalid. I've verified that the form shows the control as having the proper input and the rawvalidators property only shows the required validator.

Any ideas on what might be wrong or how I could further troubleshoot this issue?

2
  • You don't appear to be using any features of reactive forms because I can see that you are using [(ngModel)] on your input field where as I would expect to see formControlName="xxx" instead. I think you might to look up reactive forms first :) Commented Mar 23, 2021 at 15:02
  • docs are very thorough: angular.io/guide/reactive-forms Commented Mar 23, 2021 at 15:35

1 Answer 1

1

Looks like a template driven form.

You shouldn't use ngModel with reactive forms use formControlName instead if you want a reactive form. And if you have side affects subscribe to valueChanges of the control instead of using (input).

Also when setting a single input use patchValue, when setting the entire form's values use setValue.

You may need to set the formGroupName on your parent div of the input when creating things like this dynamically.

Sign up to request clarification or add additional context in comments.

6 Comments

Just a note, with reactive form you should not need a change event to set the form controls value and mark it dirty. This is something you probably did because you are mixing reactive and template driven form concepts. You for sure have to do that sometimes on complex input components to set values on the form in the controller. But something as simple as an input shouldn't need the value change method with reactive forms.
If I don't use ngModel, what property should I use instead to bind the form value?
fromControlName="<nameOfControl>" where the name is the name you give it in the FormBuilder. To set initial values on the form, you would use either many patchValue for each control or a setValue for the entire form in the init of the component. You can also give default values when you create the control, but those don't always work well, I usually have a patchValue method called in the init or in a subscribe to get the data from the backend. You need to read up on reactive forms a bit because what is shown above is template driven.
Gave this a shot and now none of the validation or value binding works. The form has the abstractControls and the control shows - but changing the value no longer does anything
Spoke too soon. Needed to add a second level of [formGroup] directives. The original problem still exists, but the code is cleaner now. That alone is worth an upvote
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.