0

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.

2
  • If you want async validator to check uniqness name or something I recomended this link: medium.com/@tomaszsochacki/… - nice and simple example. And if you use material check the tag <mat-error> . Secondly you should replace min() with minLength() Commented Jul 25, 2020 at 21:26
  • Welcome to StackOverflow. On a sidenote: Please try to ask a single question. Asking two will get you half-answers . It could even be a reason to close your question. Commented Jul 25, 2020 at 21:47

3 Answers 3

1

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) ]);
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.