Custom validator | Fromulários | Angular
- Custom validator | Fromulários | Angular
ValidatorFn, ValidationErrors
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
export function uppercaseValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const valid = /^[A-Z]+$/.test(control.value);
return valid ? null : { uppercase: { value: control.value } };
};
}
Add and Remove validator dynamically
this.form.controls.yearOfBirth.valueChanges.pipe(
tap(() => this.form.controls.passport.markAsDirty()),
startWith(this.form.controls.yearOfBirth.value)
).subscribe(
yearOfBirth => {
this.isAdult(yearOfBirth)
? this.form.controls.passport.addValidators(Validators.required)
: this.form.controls.passport.removeValidators(Validators.required);
this.form.controls.passport.updateValueAndValidity();
}
);
AsyncValidatorFn
Um AsyncValidatorFn é uma função de validação assíncrona que retorna um Promise ou Observable que emite um objeto ValidationErrors ou null. Ele é útil para validações que dependem de operações assíncronas, como chamadas a APIs.
Exemplo de Async Validator
Vamos criar um validador assíncrono que verifica se um nome de usuário já está em uso.
Passo 1: Criar a Função de Validação Assíncrona
import { AbstractControl, ValidationErrors, AsyncValidatorFn } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { delay, map } from 'rxjs/operators';
export function usernameValidator(existingUsernames: string[]): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
return of(existingUsernames).pipe(
delay(1000), // Simula uma chamada de API com atraso de 1 segundo
map(usernames => {
const usernameTaken = usernames.includes(control.value);
return usernameTaken ? { usernameTaken: { value: control.value } } : null;
})
);
};
}
Passo 2: Usar o Async Validator no Formulário
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { usernameValidator } from './username-validator'; // Certifique-se de ajustar o caminho conforme necessário
@Component({
selector: 'app-async-validator-form',
template: `
<form [formGroup]="form">
<label for="username">Username:</label>
<input id="username" formControlName="username">
<div *ngIf="form.get('username').hasError('usernameTaken')">
Este nome de usuário já está em uso.
</div>
<button type="submit" [disabled]="form.invalid">Submit</button>
</form>
`
})
export class AsyncValidatorFormComponent {
form: FormGroup;
existingUsernames = ['user1', 'user2', 'user3']; // Simula nomes de usuário existentes
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
username: ['', {
validators: [Validators.required],
asyncValidators: [usernameValidator(this.existingUsernames)],
updateOn: 'blur' // Validação assíncrona será disparada no evento 'blur'
}]
});
}
}
Neste exemplo, criamos um validador assíncrono usernameValidator que verifica se um nome de usuário já está em uso. Usamos esse validador no campo username do formulário Angular e exibimos uma mensagem de erro se o nome de usuário já estiver em uso.
usernameValidator: Função de validação assíncrona que retorna umObservableque emite um objetoValidationErrorsse o nome de usuário já estiver em uso, ounullcaso contrário.updateOn: 'blur': Configura o controle para disparar a validação assíncrona no eventoblur(quando o campo perde o foco).
Os validadores assíncronos são úteis para validações que dependem de operações assíncronas, como verificações de disponibilidade de nomes de usuário ou validações baseadas em chamadas a APIs.