Introduction: Why is Your Angular Form Screaming an Error?
\nHave you ever encountered this situation: you're writing a beautiful form in Angular Material, everything seems perfect, but the browser console suddenly displays a message:
\nmat-form-field must contain a MatFormFieldControl\nOr, if you're using strict TypeScript mode, something like this might appear:
\nError: mat-form-field must contain a MatFormFieldControl. Did you forget to add a directive that implements MatFormFieldControl?\nThis is one of the most popular errors on Stack Overflow (thousands of views!), and today we'll break it down thoroughly. You'll learn not only how to fix this problem, but also why it occurs. And most importantly — you'll learn how to create your own controls for Angular Material if the standard MatInput doesn't suit your needs.
Let's go! 🚀
\n\nWhat is MatFormFieldControl and Why is it Needed?
\nBefore treating the error, let's understand the anatomy of Angular Material. mat-form-field is a container that adds Material Design styling (label, underline, hints, errors). But by itself, it doesn't display anything. It needs a "child" — a directive or component that implements the MatFormFieldControl interface.
This interface (or abstract class) describes how the control interacts with the form: how to get the value, how to show an error, how to handle focus. The standard implementation is MatInput. If you write:
<mat-form-field>\n <input matInput placeholder="Name">\n</mat-form-field>\n— the matInput directive automatically implements MatFormFieldControl.
The error occurs when Angular doesn't find any child element with such an implementation. For example:
\n<mat-form-field>\n <input placeholder="Name"> <!-- No matInput! -->\n</mat-form-field>\nOr when you try to use a custom component that hasn't implemented the interface.
\n\nTypical Causes of the Error (and How to Fix Them)
\n\n1. Forgot to Add the matInput Directive
\nThe most trivial reason. You simply didn't specify matInput on the <input> element.
Incorrect:
\n<mat-form-field>\n <input placeholder="Email">\n</mat-form-field>\nCorrect:
\n<mat-form-field>\n <input matInput placeholder="Email">\n</mat-form-field>\nAlso check that you have imported MatInputModule into your module:
import { MatInputModule } from '@angular/material/input';\n\n@NgModule({\n imports: [MatInputModule]\n})\nexport class AppModule { }\n\n2. Using the Wrong HTML Element
\nMatInput only works with <input> and <textarea>. If you try to wrap a regular <div> or <select> (without mat-select) in mat-form-field, you'll get an error.
Incorrect:
\n<mat-form-field>\n <div>Some content</div>\n</mat-form-field>\nCorrect: use the appropriate Material components:
\n<mat-form-field>\n <mat-select placeholder="City">\n <mat-option value="1">Moscow</mat-option>\n </mat-select>\n</mat-form-field>\nFor mat-select, you need to import MatSelectModule.
3. Custom Component Does Not Implement MatFormFieldControl
\nThis is a more complex case. Let's say you created your own component for date input or rating. Angular Material doesn't know about it. You need to explicitly "teach" it.
\n