Question
Angular formControl Error with Material Autocomplete: Why It Happens and How to Fix It
Question
I am trying to use the Angular Material Autocomplete component in an Angular 2 project. I added the following template code:
<md-input-container>
<input mdInput placeholder="Category" [mdAutocomplete]="auto" [formControl]="stateCtrl">
</md-input-container>
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let state of filteredStates | async" [value]="state">
{{ state }}
</md-option>
</md-autocomplete>
My component looks like this:
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { FormControl } from "@angular/forms";
@Component({
templateUrl: "./edit_item.component.html",
styleUrls: ["./edit_item.component.scss"]
})
export class EditItemComponent implements OnInit {
stateCtrl: FormControl;
states = [/* some data */];
filteredStates: any;
constructor(private route: ActivatedRoute, private router: Router) {
this.stateCtrl = new FormControl();
this.filteredStates = this.stateCtrl.valueChanges
.startWith(null)
.map( => .(name));
}
(): {}
() {
val
? ..( (val, ).(s))
: .;
}
}
I get this error:
Can't bind to 'formControl' since it isn't a known property of 'input'
It seems like Angular cannot find the formControl directive. What causes this error, and how should it be fixed?
Short Answer
By the end of this page, you will understand why Angular shows the error Can't bind to 'formControl' since it isn't a known property of 'input', how FormControl is connected to Angular Reactive Forms, and which module imports are required when using Angular Material Autocomplete with a reactive form input.
Concept
formControl is not a normal HTML attribute. It is an Angular directive provided by the Reactive Forms system.
When Angular sees this:
<input [formControl]="stateCtrl">
it tries to find a directive named formControl. If the Angular module that declares your component has not imported ReactiveFormsModule, Angular does not know what formControl means, so it throws this error:
Can't bind to 'formControl' since it isn't a known property of 'input'
Why this matters
In Angular, components do not automatically get access to every directive in the framework. Directives such as:
ngIfngForngModelformControlformGroup
are made available by importing the correct Angular modules.
For reactive forms:
FormControlclass comes from
Mental Model
Think of Angular templates like a workshop.
- Your component class brings the tools you create yourself.
- Angular modules bring the tools the workshop already provides.
You created this tool in code:
this.stateCtrl = new FormControl();
But in the template, you also want to use Angular's built-in formControl tool:
<input [formControl]="stateCtrl">
If ReactiveFormsModule is not imported, it is like trying to use a tool that was never delivered to the workshop. Angular looks around, cannot find it, and reports that formControl is not a known property.
Syntax and Examples
To use reactive form controls in Angular, you need two things:
- A
FormControlin the component class ReactiveFormsModuleimported in the Angular module
Core syntax
import { FormControl, ReactiveFormsModule } from '@angular/forms';
export class ExampleComponent {
nameCtrl = new FormControl('');
}
<input [formControl]="nameCtrl">
Working example
Component
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import 'rxjs/add/operator/startWith';
;
({
: ,
:
})
{
stateCtrl = ();
states = [, , , ];
filteredStates = ..
.()
.( .(value));
() {
..(
state.().((value || ).())
);
}
}
Step by Step Execution
Consider this small example:
nameCtrl = new FormControl('');
<input [formControl]="nameCtrl">
imports: [ReactiveFormsModule]
What happens step by step
- Angular loads the module.
- The module imports
ReactiveFormsModule. - That module registers directives such as:
formControlformGroupformControlName
- Angular creates the component instance.
- The component creates
nameCtrlas aFormControl. - Angular parses the template.
- It sees
[formControl]="nameCtrl"on the<input>. - Because
ReactiveFormsModuleis imported, Angular recognizes as a valid directive.
Real World Use Cases
Reactive form controls are used in many real applications:
Search and autocomplete
- Product search boxes
- City or country suggestions
- User mention dropdowns
- Category selectors
Forms with validation
- Registration forms
- Login forms
- Shipping address forms
- Payment details
Dynamic UI behavior
- Filter a list as the user types
- Enable or disable buttons based on input
- Show validation errors immediately
- Transform user input before submission
API-driven forms
A FormControl can listen to valueChanges and trigger logic like:
- filtering local arrays
- calling APIs for suggestions
- debouncing user input
- validating values asynchronously
Autocomplete is a very common case because the input value changes often and the UI must react immediately.
Real Codebase Usage
In real projects, developers usually use reactive forms with a few common patterns.
Module-level setup
Teams usually create a feature module and import form modules there, instead of importing everything everywhere.
imports: [CommonModule, ReactiveFormsModule]
Guarding against null or empty values
When autocomplete starts, the value may be null, '', or even an object in more advanced cases.
filterStates(value: string) {
const search = (value || '').toLowerCase();
return this.states.filter(state => state.toLowerCase().includes(search));
}
Using valueChanges for live filtering
this.filteredStates = this.stateCtrl.valueChanges
.()
.( .(value));
Common Mistakes
Here are the most common beginner mistakes behind this error.
1. Importing FormControl but not ReactiveFormsModule
This is the exact issue in your example.
Broken
import { FormControl } from '@angular/forms';
This only makes the class available in TypeScript.
Fix
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [ReactiveFormsModule]
})
export class YourModule {}
2. Importing the module in the wrong Angular module
If EditItemComponent belongs to ItemsModule, importing ReactiveFormsModule only in AppModule may not help.
Fix
Import it in the module that declares the component.
3. Mixing template-driven and reactive forms without understanding the difference
Comparisons
Here are the related Angular concepts that are easy to confuse.
| Concept | What it is | Needed import | Typical use |
|---|---|---|---|
FormControl | TypeScript class | @angular/forms | Create and manage a control in code |
formControl | Template directive | ReactiveFormsModule | Bind an input to a FormControl |
ngModel | Template-driven forms directive | FormsModule | Simple two-way form binding |
formControlName | Directive used inside a |
Cheat Sheet
Quick fix for this error
If you see:
Can't bind to 'formControl' since it isn't a known property of 'input'
check this first:
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [ReactiveFormsModule]
})
export class YourModule {}
Reactive forms essentials
In the component
import { FormControl } from '@angular/forms';
nameCtrl = new FormControl('');
In the template
<input [formControl]="nameCtrl">
In the module
import { ReactiveFormsModule } from ;
FAQ
Why does Angular say formControl is not a known property?
Because the formControl directive is not available in the current Angular module. Usually, ReactiveFormsModule is missing.
Is importing FormControl enough?
No. That only lets you use the FormControl class in TypeScript. The template directive still requires ReactiveFormsModule.
Should I import FormsModule or ReactiveFormsModule?
Use ReactiveFormsModule for [formControl]. Use FormsModule for [(ngModel)].
Why does this happen even though my code compiles?
TypeScript can compile your component class, but Angular template compilation fails because the directive is unavailable in the template scope.
Do I also need Angular Material imports?
Yes, for Material-specific directives like mdInput and mdAutocomplete. Those are separate from reactive forms.
Does the import go in ?
Mini Project
Description
Build a small category search input using Angular reactive forms and Angular Material autocomplete. This project demonstrates how a FormControl is connected to an input, how valueChanges can filter results, and why the correct Angular module imports are required.
Goal
Create a working autocomplete field that filters a list of categories as the user types, without triggering the formControl binding error.
Requirements
- Create a component with a
FormControlfor the input. - Display an Angular Material autocomplete dropdown.
- Filter a local list of categories as the user types.
- Import the required Angular forms module in the correct Angular module.
- Import the required Angular Material modules for the input and autocomplete.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular formGroup Error Explained: Fixing 'Can't bind to formGroup' in Reactive Forms
Learn why Angular shows 'Can't bind to formGroup' and how to fix it by importing ReactiveFormsModule correctly.