MatFormFieldControl: analizando el error de una vez por todas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué su formulario Angular grita un error?

\n

¿Alguna vez se ha encontrado con esta situación: escribe un formulario hermoso en Angular Material, todo parece perfecto, pero la consola del navegador de repente muestra el mensaje:

\n
mat-form-field must contain a MatFormFieldControl
\n

O, si usa el modo estricto de TypeScript, puede aparecer algo como:

\n
Error: mat-form-field must contain a MatFormFieldControl. Did you forget to add a directive that implements MatFormFieldControl?
\n

Este es uno de los errores más populares en Stack Overflow (¡miles de visitas!), y hoy lo analizaremos de arriba a abajo. Aprenderá no solo cómo solucionar este problema, sino también por qué ocurre. Y lo más importante: aprenderá a crear sus propios controles para Angular Material, si el estándar MatInput no se adapta a sus necesidades.

\n

¡Allá vamos! 🚀

\n\n

¿Qué es MatFormFieldControl y para qué sirve?

\n

Antes de curar el error, entendamos la anatomía de Angular Material. mat-form-field es un contenedor que agrega la estilización de Material Design (etiqueta, subrayado, sugerencias, errores). Pero por sí mismo no muestra nada. Necesita un "hijo": una directiva o componente que implemente la interfaz MatFormFieldControl.

\n

Esta interfaz (o clase abstracta) describe cómo el control interactúa con el formulario: cómo obtener el valor, cómo mostrar un error, cómo manejar el foco. La implementación estándar es MatInput. Si escribe:

\n
<mat-form-field>\n  <input matInput placeholder="Nombre">\n</mat-form-field>
\n

— la directiva matInput implementa automáticamente MatFormFieldControl.

\n

El error ocurre cuando Angular no encuentra ningún elemento hijo con dicha implementación. Por ejemplo:

\n
<mat-form-field>\n  <input placeholder="Nombre"> <!-- ¡Sin matInput! -->\n</mat-form-field>
\n

O cuando intenta usar un componente personalizado que no ha conectado la interfaz.

\n\n

Causas típicas del error (y cómo solucionarlas)

\n\n

1. Olvidó agregar la directiva matInput

\n

La causa más simple. Simplemente no especificó matInput en el elemento <input>.

\n

Incorrecto:

\n
<mat-form-field>\n  <input placeholder="Email">\n</mat-form-field>
\n

Correcto:

\n
<mat-form-field>\n  <input matInput placeholder="Email">\n</mat-form-field>
\n

Verifique también que haya importado MatInputModule en su módulo:

\n
import { MatInputModule } from '@angular/material/input';\n\n@NgModule({\n  imports: [MatInputModule]\n})\nexport class AppModule { }
\n\n

2. Usa el elemento HTML incorrecto

\n

MatInput solo funciona con <input> y <textarea>. Si intenta envolver en mat-form-field un <div> común o un <select> (sin mat-select), obtendrá el error.

\n

Incorrecto:

\n
<mat-form-field>\n  <div>Algún contenido</div>\n</mat-form-field>
\n

Correcto: use los componentes Material correspondientes:

\n
<mat-form-field>\n  <mat-select placeholder="Ciudad">\n    <mat-option value="1">Madrid</mat-option>\n  </mat-select>\n</mat-form-field>
\n

Para mat-select necesita importar MatSelectModule.

\n\n

3. El componente personalizado no implementa MatFormFieldControl

\n

Este es un caso más complejo. Supongamos que creó su propio componente para ingresar una fecha o una calificación. Angular Material no lo conoce. Es necesario "enseñarle" explícitamente.

\n

Blogs

Book Recommendations