vindict
vindict

Reputation: 151

Add dynamic form fields and validations to formArray in Angular

I'm trying to build a dynamic form, where the field names and their validations will come from an API

so I'm creating a simple form, with a formArray inside, something like this:

this.myForm = this.formBuilder.group({
  dynamicFields: this.formBuilder.array([])  // where I will be pushing the custom fields and their validations
});

Just for testing, I'm trying to add a field 'country', with 2 validations (required, minLength of 22)

this is what I'm doing:

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);
(this.myForm.get('dynamicFields') as FormArray).push(customControl);

I also created the bellow getter to use it in my template

getDynFields() {
  return this.myForm.get('dynamicFields') as FormArray;
}

and this is the template:

<form [formGroup]="myForm">
  <div formArrayName="dynamicFields">
    <div *ngFor="let control of getDynFields().controls; let i = index">
      <mat-form-field>
        <input
          [formControlName]="i"
          matInput
          type="text"
          placeholder="{{ control.value }}"
        />
      </mat-form-field>
    </div>
  </div>
</form>

what is happening (as you see below) is that for the field value and placeholder I'm getting 'country' pre-populated (I only want the placeholder to be 'country' and the value should be empty of course) And the second issue is that only required validation is working, minLength is not doing anything

enter image description here

Thanks in advance.

Upvotes: 0

Views: 1791

Answers (3)

Rob Monhemius
Rob Monhemius

Reputation: 5144

Validators.min() vs Valiadators.minLength()

You are using Validators.min(). This is intented to check numerical input values, not to get the length of a string:

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);

Use Validators.minLength() instead:

let customControl = this.fb.control('country', [ Validators.required, Validators.minLength(10) ]);

The first parameter of a FormControl is its value

The first parameter of a FormControl is its value. You are setting a value of 'country' in your example:

let customControl = this.fb.control('country', [ Validators.required, Validators.minLength(10) ]);

If you set it to null you will see whatever placeholder you have set.

let customControl = this.fb.control(null, [ Validators.required, Validators.minLength(10) ]);

You can implement the placeholder however you want in your template. As a string or a reference to some objects property.

Upvotes: 1

Adil Khalil
Adil Khalil

Reputation: 2121

FormControl takes 'state' or default value as first param while initialising. Also for min length, you should use Validators.minLength(n).

constructor(formState: any = null, validatorOrOpts?: ValidatorFn | AbstractControlOptions | ValidatorFn[], asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[])

instead of this

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);

you should do this

let customControl = this.fb.control('', [ Validators.required, Validators.minLength(10) ]);

Upvotes: 1

Dipraj Shahane
Dipraj Shahane

Reputation: 13

For min length please use Validators.minLength(22)
Please refer: https://angular.io/api/forms/Validators#minLength for more info.
min(10) used to add validation as minimum value can be 10.

Upvotes: 0

Related Questions