ifValidator & ifAsyncValidator

ngx-lift provides utility functions for creating conditional validators in Angular Reactive Forms. Conditional validators allow you to apply specified validator functions based on a given condition. There are two main functions exported: ifValidator for synchronous validators and ifAsyncValidator for asynchronous validators.

Examples

Example 1: Conditional Required Validator

Require a reason input and an email input only when the "Sorry" option is selected. The required validator is applied to the text input control only when the "Sorry" option is chosen.

Field required only when you choose Sorry
Field required only when you choose Sorry
import {ifValidator} from 'ngx-lift';
import {Component} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';

@Component({
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form">
      <clr-radio-container>
        <label>Do you like this tool?</label>
        <clr-radio-wrapper>
          <input type="radio" clrRadio name="choice" value="LIKE" [formControl]="form.controls.choice" (change)="changeChoice()" />
          <label>Of course 😜</label>
        </clr-radio-wrapper>
        <clr-radio-wrapper>
          <input type="radio" clrRadio name="choice" value="UNLIKE" [formControl]="form.controls.choice" (change)="changeChoice()" />
          <label>Sorry 😅</label>
        </clr-radio-wrapper>
      </clr-radio-container>

      <clr-input-container>
        <label>Email</label>
        <input clrInput type="text" [formControl]="form.controls.email" />
        <clr-control-error *clrIfError="'required'">Required</clr-control-error>
        <clr-control-error *clrIfError="'email'">Invalid email</clr-control-error>
      </clr-input-container>

      <clr-input-container>
        <label>Reason why you don't like</label>
        <input clrInput type="text" [formControl]="form.controls.reason" />
        <clr-control-error *clrIfError="'required'">Required</clr-control-error>
      </clr-input-container>
    </form>
  `
})
export class IfValidatorComponent {
  validator = ifValidator(
    () => this.form?.controls.choice.value === 'UNLIKE',
    [Validators.required],
    // add mismatch validation functions if needed
  );

  form = new FormGroup({
    choice: new FormControl('', Validators.required),
    email: new FormControl('', [this.validator, Validators.email]),
    reason: new FormControl('', this.validator),
  });

  // updateValueAndValidity whenever the condition is changed.
  changeChoice() {
    this.form.controls.email.updateValueAndValidity();
    this.form.controls.reason.updateValueAndValidity();
  }
}

Example 2: ifAsyncValidator

ifAsyncValidator shares similarities with ifValidator but differs in that it accepts two parameters: the condition and an AsyncValidation function, designed specifically for handling asynchronous operations.

import {ifAsyncValidator} from 'ngx-lift';
import {Component} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
import {of} from 'rxjs';
import {delay} from 'rxjs/operators';

@Component({
  imports: [ReactiveFormsModule],
})
export class IfAsyncValidatorComponent {
  asyncValidator = ifAsyncValidator(
    () => this.form?.controls.enableAsync.value === true,
    (control) => {
      // Simulate async validation
      return of(null).pipe(delay(1000));
    }
  );

  form = new FormGroup({
    enableAsync: new FormControl(false),
    asyncField: new FormControl('', null, this.asyncValidator),
  });

  toggleAsync() {
    this.form.controls.asyncField.updateValueAndValidity();
  }
}

API Reference

ifValidator

Creates a conditional validator that applies validator functions based on a condition.

Signature

ifValidator(
  condition: () => boolean,
  trueValidatorFn: ValidatorFn | ValidatorFn[],
  falseValidatorFn?: ValidatorFn | ValidatorFn[]
): ValidatorFn

Parameters

  • condition: () => boolean

    A function that determines whether the validators should be applied. Returns true to apply trueValidatorFn, false to apply falseValidatorFn (if provided).

  • trueValidatorFn: ValidatorFn | ValidatorFn[]

    The validator function or array of validator functions to be applied when the condition is true.

  • falseValidatorFn?: ValidatorFn | ValidatorFn[]

    (Optional) The validator function or array of validator functions to be applied when the condition is false.

Returns

A validator function that can be used with Angular Reactive Forms.

ifAsyncValidator

Creates a conditional async validator that applies async validator functions based on a condition.

Signature

ifAsyncValidator(
  condition: () => boolean,
  asyncValidatorFn: AsyncValidatorFn
): AsyncValidatorFn

Parameters

  • condition: () => boolean

    A function that determines whether the async validator should be applied.

  • asyncValidatorFn: AsyncValidatorFn

    The async validator function to be applied when the condition is true.

Returns

An async validator function that can be used with Angular Reactive Forms.