Ir al contenido

NgxControlError

Created by Robby Rabbitman

NgxControlError es una directiva estructural para mostrar consistentemente los errores de los controles de formulario, reduciendo al mismo tiempo la redundancia de código.

import { NgxControlError } from 'ngxtension/control-error';
<label>
<b>Nombre</b>
<input type="text" [formControl]="name" />
<strong *ngxControlError="name; track: 'required'">
Se requiere el nombre.
</strong>
</label>

La plantilla se renderizará cuando el control esté en un estado de error y sus errores incluyan el/los error(es) rastreado(s).

Sin NgxControlError:

<label>
<b>Nombre</b>
<input type="text" [formControl]="name" />
@if (name.hasError('required') && (name.touched || form.submitted)) {
<strong>Se requiere el nombre.</strong>
}
</label>

En un formulario también puedes pasar el nombre del control en lugar de la instancia.

<form [formGroup]="form">
<label>
<b>Nombre</b>
<input type="text" formControlName="name" />
<strong *ngxControlError="'name'; track: 'required'">
Se requiere el nombre.
</strong>
</label>
</form>

Un StateMatcher define cuándo el control proporcionado está en un estado de error. Un StateMatcher es una función que devuelve un observable. Cada vez que el StateMatcher emite un valor, la directiva verifica si debe renderizar u ocultar su plantilla: La directiva renderiza su plantilla cuando el StateMatcher emite true y los errores del control incluyen al menos un error rastreado, de lo contrario, su plantilla estará oculta.

export type StateMatcher = (
control: AbstractControl,
parent?: FormGroupDirective | NgForm,
) => Observable<boolean>;

Por defecto, se considera que el control está en un estado de error cuando 1. su estado es INVALID y 2. está touched o su formulario ha sido submitted.

Puedes anular este comportamiento:

/**
* Un control está en un estado de error cuando su estado es inválido.
* Emite siempre que statusChanges emita.
* Puedes querer agregar más fuentes, como valueChanges.
*/
export const customErrorStateMatcher: StateMatcher = (control) =>
control.statusChanges.pipe(
startWith(control.status),
map((status) => status === 'INVALID'),
);
provideNgxControlError({ errorStateMatcher: customErrorStateMatcher });
<label>
<b>Nombre</b>
<input type="text" [formControl]="name" />
<strong
*ngxControlError="name; track: 'required'; errorStateMatcher: customErrorStateMatcher"
>
Se requiere el nombre.
</strong>
</label>

Puedes iterar sobre todos los errores posibles y pasar los errors al pipe de traducción:

<label>
<b>Correo</b>
<input type="email" [formControl]="mail" />
@for (error of ['required', 'email', 'myCustomError']; track error) {
<strong *ngxControlError="mail; track: error">
{{ "RUTA.A.ERRORES.CONTROL.CORREO." + error | translate: mail.errors }}
</strong>
}
</label>
<mat-form-field>
<mat-label>Nombre</mat-label>
<input matInput [formControl]="name" />
<mat-error *ngxControlError="name; track: 'required'">
Se requiere el nombre.
</mat-error>
</mat-form-field>