Tzimpo
Tzimpo

Reputation: 1009

Dynamically add validator

I have a formArray and on click i am calling addReps method to push a new formGroup.I want to add some validators dynamically with setValidators method but when i'm doing this i'm getting error: Cannot read property 'setValidators' of undefined. My form working fine but i can't understand why i'm getting this error.Am i doing something wrong with my formControl access this.reps.controls["mobileNumber"]?

constructor(private fb: FormBuilder, private stateService: StateService, private apiService: ApiService) {
   this.form = this.fb.group({
     reprepresentative: this.fb.array([]),
   });
}

addReps() {
  this.reps = this.form.controls.reprepresentative as FormArray;
  this.reps.push(this.fb.group({
    firstname: ['', [Validators.required,
     Validators.minLength(2),
     this.ValidateNames
    ]],
    surname: ['', [Validators.required,
     Validators.minLength(2),
     this.ValidateNames
   ]],
   mobileNumber: ['', [Validators.required,
    Validators.pattern(/^(69[0-9])[0-9]{7}$/)
    ]],
  isInitiator: false,
  editRep: true
  }));
  this.reps.controls["mobileNumber"].setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]);
  this.reps.controls["mobileNumber"].updateValueAndValidity();
}

SameMobileValidator(formControl: AbstractControl){
   let repList = this.stateService.reprepresentativeList;
   const found = repList.some(el => el.MobilePhone == formControl.value)
   if(!found) return null;
   else { return { mismatch: true }; }
}

I also try this:

  this.reps.get("mobileNumber").setValidators([Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/),this.ValidateNames]);
this.reps.get("mobileNumber").updateValueAndValidity();

But i'm getting the same error

Upvotes: 0

Views: 840

Answers (3)

Ghoul Ahmed
Ghoul Ahmed

Reputation: 4836

this.reps is a formArray, so you should change

this.reps.controls["mobileNumber"].setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]);

by

const reprepresentativeControl = this.form.get('reprepresentative');
reprepresentativeControl.controls.forEach(c => c.get("mobileNumber").setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]));
reprepresentativeControl.updateValueAndValidity();

Upvotes: 1

Chellappan வ
Chellappan வ

Reputation: 27471

Since ForArray are index based you have use index value to get specific formGroup controls.

Try this:

this.reps.at(0).get('mobileNumber').setValidators([=[Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/),this.ValidateNames])

Upvotes: 1

KamLar
KamLar

Reputation: 428

First of all, don't use .controls to get specified control. Use get(). You are getting an exception becouse your this.reps is FormArray which when you access to controls property, you are getting object like this:

{
    1: [formControl],
    2: [formControl],
    3: [formControl]
}

As you can see, there is no field mobileNumber in this.reps. You have to directly access to formControl to get mobileNumber formControl. Or you can directly add validator to the field while you are building your form like have done earlier. If your validation logic validate f.e. number uniqueness, you have to attach validator on your FormArray (or FormGroup, depending on what you use) not directly on FormControl.

Upvotes: 1

Related Questions