Home > Software design >  Async validator not executing
Async validator not executing

Time:03-11

Stackblitz: https://angular-ivy-mhot2x.stackblitz.io

For my Angular (13.0.2) application, I've created a validator to check if a URL is already in use (i.e. GET <URL> does not return 404). However, while I can see the function being called, I don't see the HTTP request happening. What am I doing wrong?

Validator:

mport { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
import {
  AsyncValidatorFn,
  AbstractControl,
  ValidationErrors,
} from '@angular/forms';
import { Observable, of } from 'rxjs';

// h/t: https://medium.com/@rinciarijoc/angular-custom-async-validators-13a648d688d8
@Injectable({
  providedIn: 'root',
})
export class UrlExistsService {
  constructor(private http: HttpClient) {}

  public urlExists(url: string): Observable<boolean> {
    console.debug(`Check url exists: ${url}`)
    if (!url) {
      return of(false)
    }
    return this.http
      .get(url, { observe: 'response', responseType: 'text' })
      .pipe(
        map((res) => {
          console.debug('Check URL result', { res });
          return res.status !== 404;
        })
      );
  }

  public urlDoesNotExistValidator() {
    const fn: AsyncValidatorFn = (
      control: AbstractControl
    ): Observable<ValidationErrors | null> => {
      return this.urlExists(control.value).pipe(
        map((result: boolean) => {
          console.debug('URL exists?', result);
          return result ? { urlExists: true } : null;
        })
      );
    };
    return fn;
  }
}

CodePudding user response:

You need to add the asyncValidators as the 3rd argument of the FormControl constuctor. docs

In your example it should be:

this.url = new FormControl('', [],[this.urlExistsService.urlDoesNotExistValidator()])

cheers

  • Related