1

I created the following angular async validator class, following the documentation:

import { Injectable } from '@angular/core';
import {
  AsyncValidator,
  AbstractControl,
  ValidationErrors,
} from '@angular/forms';
import { XService } from '../../pages/x/x.service';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable()
export class UniqueXValidator
  implements AsyncValidator {
  constructor(
    private xService: XService,
  ) {}

  validate(ctrl: AbstractControl): Observable<ValidationErrors | null> {
    return this.xService.checkExists(ctrl.value).pipe(
      map(exists =>
        exists ? { uniqueX: true } : null,
      ),
      catchError(() => of(null)),
    );
  }
}

Then I try to programmatically attach it to a form control this way:

    this.form.controls['code'].setAsyncValidators(
      UniqueXValidator,
    );

I am getting the following error message displayed as a tooltip on vs code when hovering "UniqueXValidator" in the second piece of code:

    Argument of type 'typeof UniqueXValidator' is not assignable to parameter of type 'AsyncValidatorFn | AsyncValidatorFn[]'.
  Type 'typeof UniqueXValidator' is missing the following properties from type 'AsyncValidatorFn[]': pop, push, concat, join, and 25 more.ts(2345)

EDIT: It was maybe a problem of compatibility between my angular version (7) and the documentation's (11)

2
  • You need to specify method Commented May 6, 2021 at 6:48
  • Could you please explain? @BojanKogoj Commented May 6, 2021 at 6:50

2 Answers 2

3

Use AsyncValidatorFn instead AsyncValidator like this:

usernameValidator(): AsyncValidatorFn {
  return (control: AbstractControl): Observable<ValidationErrors | null> => {
    return this.checkIfUsernameExists(control.value).pipe(
      map(res => {
        // if res is true, username exists, return true
        return res ? { usernameExists: true } : null;
        // NB: Return null if there is no error
      })
    );
  };
}

then you can add a validator at initialization:

this.fb.group({
  username: [
    null, [Validators.required],  [this.usernameService.usernameValidator()]
  ]
});

or at runtime:

this.form.controls['code'].setAsyncValidators(
  this.usernameService.usernameValidator()
);
Sign up to request clarification or add additional context in comments.

Comments

0

setAsyncValidators expects array not single validator

Also u dont need @Injectable() on UniqueXValidator

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.