how do i validate duplicates for dynamically added form fields?

In this SO you has a custom validation over a FormArray. The problem if you use a custom validation over a formArray is that is checked always you change any value in the formArray (any change in repName, or in passport or in phoneName)

You can create a custom validator over a Form Control that take account others controls

  checkIfUnique(index) {
    return (control: FormControl) => {
      //try get the form array
      //control.parent is the FormGroup, control.parent.parent is the formArray
      const formArray =
        control.parent && control.parent.parent
          ? (control.parent.parent as FormArray)
          : null;
      if (formArray && formArray.controls.length) {
        for (let i = index - 1; i >= 0; i--) {
          if (
            (formArray.at(i) as FormGroup).get("repName").value == control.value
          )
            return { errorRepeat: true };
        }
      }
    };
  }

You need, when make the formGroup of the formArray, pass to the validator the “index” of element. So your need change your function createRep

//pass the index
createRep(index:number): FormGroup {
    return this.fb.group({
      repName: ['', [Validators.required,this.checkIfUnique(index) ]],
      passport: ['', Validators.required],
      phoneNumber: ['', Validators.required]
    });
  }

Well, the last we need is, when change a value of any ‘repName’, check the rest of controls. Remember that Angular check the formControl that you change, but not the rest, so if repName[0]="a" and repName[1]="b", when change repName[0] to “b” Angular don’t check repName[1]. So we create a function

  checkFormArray()
  {
    this.detailsFormArray.controls.forEach(x=>{
      (x as FormGroup).get('repName').updateValueAndValidity()
    })
  }
  //I use a getter of the formArray
  get detailsFormArray() {
     return (this.verificationForm.get("repDetails") as FormArray)
  }

And in the input we call to the function

  <input formControlName="repName" (input)="checkFormArray()">

You can see the stackblitz

NOTE: I remove the tag angularjs from your question (your question is only about angular)

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top