uniqueValidator

The uniqueValidator is a custom Angular Forms validator designed to check for uniqueness across multiple fields within a FormArray or FormGroup. It ensures that each control's value is unique among all other controls within the array or group.

Examples

Example 1: Array of FormControls

If you have an array of individual FormControls and want to ensure uniqueness, attach UniqueValidator.unique() to the FormArray you want to validate.

Control value should be unique
Control value should be unique
import {UniqueValidator} from 'ngx-lift';
import {Component, inject} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule} from '@angular/forms';

@Component({
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form1">
      <ng-container formArrayName="demo1">
        @for (control of form1.controls.demo1.controls; track $index; let i = $index) {
          <clr-input-container>
            <label [attr.for]="i">Control {{ i + 1 }}</label>
            <input clrInput type="text" [formControlName]="i" (blur)="validateControlByIndex(i)" />
            <clr-control-helper>Control value should be unique</clr-control-helper>
            <clr-control-error *clrIfError="'notUnique'">Duplicated</clr-control-error>
          </clr-input-container>
        }
      </ng-container>
    </form>
  `
})
export class UniqueValidatorExampleComponent {
  private fb = inject(FormBuilder);

  form1 = this.fb.group({
    demo1: this.fb.array([this.fb.control(''), this.fb.control('')], UniqueValidator.unique()),
  });

  validateControlByIndex(index: number) {
    this.form1.controls.demo1.controls[index].updateValueAndValidity();
  }
}

Example 2: Array of FormGroups with Key-Value Pairs

In a more complex scenario, imagine you have an array of FormGroups, each containing key-value pairs as FormControls. You want to ensure the uniqueness of the key controls' values (left controls below) across all groups. For this case, you can pass a control selector as the argument of UniqueValidator.unique(controlSelector).

key control should be unique
value control has not validation
key control should be unique
value control has not validation
import {UniqueValidator} from 'ngx-lift';
import {Component, inject} from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';

@Component({
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form2">
      <ng-container formArrayName="demo2">
        @for (group of form2.controls.demo2.controls; track $index; let i = $index) {
          <div [formGroup]="group" style="display: flex; gap: 1rem">
            <clr-input-container>
              <label class="clr-sr-only">key</label>
              <input
                clrInput
                [formControl]="group.controls.key"
                (blur)="validateControl(group.controls.key)"
                [size]="30"
              />
              <clr-control-helper>key control should be unique</clr-control-helper>
              <clr-control-error *clrIfError="'notUnique'">Duplicated</clr-control-error>
            </clr-input-container>
            <clr-input-container>
              <label class="clr-sr-only">value</label>
              <input clrInput [formControl]="group.controls.value" [size]="30" />
              <clr-control-helper>value control has not validation</clr-control-helper>
            </clr-input-container>
          </div>
        }
      </ng-container>
    </form>
  `
})
export class UniqueValidatorFormGroupExampleComponent {
  private fb = inject(FormBuilder);

  form2 = this.fb.group({
    demo2: this.fb.array(
      [this.fb.group({key: '', value: ''}), this.fb.group({key: '', value: ''})],
      UniqueValidator.unique((control) => (control as FormGroup<{key: FormControl<string>}>).controls.key),
    ),
  });

  validateControl(control: AbstractControl) {
    control.updateValueAndValidity();
  }
}

API Reference

UniqueValidator

Validator class that checks for uniqueness across multiple fields within a FormArray or FormGroup.

Signature

UniqueValidator.unique(controlSelector?: (control: AbstractControl) => AbstractControl): ValidatorFn

Parameters

  • controlSelector?: (control: AbstractControl) => AbstractControl

    (Optional) A function that selects which control within a FormGroup to validate for uniqueness. If not provided, validates the FormControl values directly.

    Useful when you have an array of FormGroups and want to ensure uniqueness of a specific control within each group.

Returns

A validator function that returns {notUnique: true} if duplicate values are found, or null if all values are unique.

Usage Notes

Trigger the control's updateValueAndValidity() method as needed to re-validate when values change.