Carlos Cifuentes
Referencia AngularJS → Angular

$validators / $asyncValidators en Angular moderno

Las directivas de validación que escribían en $validators y $asyncValidators pasan a ser funciones simples asociadas al control del formulario.

Antes · AngularJS
app.directive('companyEmail', function ($q, UserService) {
  return {
    require: 'ngModel',
    link: function (scope, el, attrs, ngModel) {
      ngModel.$validators.company = function (v) { return !v || v.endsWith('@acme.com'); };
      ngModel.$asyncValidators.unique = function (value) {
        return UserService.exists(value).then(function (taken) {
          if (taken) { return $q.reject(); }
        });
      };
    }
  };
});
Después · Angular
export const companyEmail: ValidatorFn = control =>
  !control.value || control.value.endsWith('@acme.com') ? null : { company: true };

export function uniqueEmail(): AsyncValidatorFn {
  const users = inject(UserService);
  return control => users.exists(control.value).pipe(
    map(taken => (taken ? { unique: true } : null)),
  );
}

// component field, so inject() has an injection context
email = new FormControl('', {
  nonNullable: true,
  validators: [Validators.required, companyEmail],
  asyncValidators: [uniqueEmail()],
});

Qué cambia

  • Una función de $validators devolvía true o false; un ValidatorFn devuelve null cuando es válido o un objeto de error como { company: true }.
  • Una promesa rechazada en $asyncValidators pasa a ser un AsyncValidatorFn que emite null o un objeto de error.
  • Con formularios reactivos no hace falta una directiva. Los validadores asíncronos corren solo después de que pasan los síncronos, igual que antes.

Consejo de migración. Un validador asíncrono corre en cada cambio de valor. Define updateOn: 'blur' en el control o agrega una espera dentro del validador, el trabajo que hacía ng-model-options debounce en AngularJS.

Relacionado

¿Planeas una migración o una plataforma de microfrontends?

En una llamada de 20 minutos me cuentas tu situación y te digo cómo la abordaría. Si todavía no vale la pena, también te lo digo.

Escríbeme por LinkedIn