1

I'm using Angular 6 with reactive forms. One of the form field is a FormArray which adds controls as the user clicks an Add button.

Within the FormArray, I would like to check whether the FormControl value already exists in the FormArray.

This works fine until the user clicks 'Add' button which resets the previous control error and marks the control as valid although it still has a duplicate value.

This is the function to add control in the form array:

onAddIPAddress() {

  if (( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length < 8) {

    const control = new FormControl(null, Validators.compose([
      Validators.required,
      Validators.pattern(this.ipaddressPattern),
      this.forbiddenIPs.bind(this),
      this.onDuplicateIPFormArray.bind(this)
    ]));


    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).push(control);


  } else {
    return;
  }

}

Then, this is the custom validator code:

onDuplicateIPFormArray(control: FormControl): {
  [s: string]: boolean
} {

  if (
    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length > 1 &&
    !( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.includes(null) &&
    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.indexOf(control.value) !== -1)

  {
    console.log(( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.indexOf(control.value));

    return {
      duplicateIP: true
    };
  }

  return null;

}

From the console, I can see the IndexOf value is incorrect but not able to understand why.

Any ideas how I can handle this ?

Thanks

2
  • As far as I understand it, you set the value of the newly created FormControl to null and afterwards use null for the indexOf Commented Jun 12, 2018 at 12:33
  • I set the initial FormControl value to null and then in the validator do the followings: - Check the FormArray length is > 1, - Check if one of the FormArray control is not null and if none is null use get the indexOf the FormControl value Commented Jun 12, 2018 at 13:05

1 Answer 1

2

Ok, so I've changed how validation should be done and it seems much better:

  • Remove custom Validator from individual FormArray controls.

  • Put the duplicate items custom validator on the FormArray itself.

if ($event.value ===
  'ip-address') {
  this.tcpudpAppFormGroup.addControl('ipaddressArray', new FormArray([], Validators.compose([
    Validators.required,
    this.onDuplicateIPFormArray.bind(this)

  ])));

Then create the FormArray validator as a standard function to detect duplicated items in an array:

onDuplicateIPFormArray() {

  if (( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray'))) {

    let counts = [];

    for (let i = 0; i < ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length; i++) {
      if (counts[( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value[i]] === undefined) {
        counts[( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value[i]] = 1;
      } else {
        console.log(counts);
        ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).controls[i].setErrors({
          duplicateIP: true
        });
        
      }
    }
  }
}

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

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.