Angular / Editorial solution guide
Resolve NG8002 for a standalone form binding
Find the actual template owner and import the directive that implements the binding instead of suppressing an unknown-property error with a broad schema.
Read-only knowledge base · No public comments
Recognize the symptoms
Angular template compilation reports an invalid property binding, often NG8002 when [formControl] has no matching directive in the template scope. The class can still pass ordinary TypeScript checking because importing FormControl creates the model but does not make its template directive available. Read the binding name and owning component in the diagnostic.
A related unknown-selector diagnostic can indicate a missing child component instead. Do not assume every template error is caused by the same module or add unrelated application providers until the failing template dependency is identified.
Understand the likely causes
- A standalone component declares its template dependencies in imports. A TypeScript import alone does not register a directive in that scope. ReactiveFormsModule supplies the reactive form directives, while template-driven NgModel uses a different import and model. Mixing the two approaches on one input is not the appropriate repair.
- The error can also be a misspelled property or a test host with different imports from the real component. A broad schema suppression can silence evidence without attaching the intended behavior. Fix the dependency at the template owner rather than assuming a root provider imports every directive globally.
Identify the exact component template scope
Find the component that owns the failing input, not merely the parent page that displays it. The contextual excerpt below requires a name FormControl and ReactiveFormsModule in that owner’s imports. It is intentionally not independently runnable. Ordinary HTML input has no native formControl property, so the framework directive must be available. Confirm spelling and whether the intended form model is reactive before editing metadata.
<input [formControl]="name">
Without the matching directive import, Angular can report NG8002. This fragment has no standalone browser result and is not executed.
Import ReactiveFormsModule at the owner
The corrected component explicitly imports the reactive directives and creates a non-nullable control. Its visible label is connected to the input id. This is a complete component definition but still needs Angular application or TestBed bootstrap and a DOM, so it remains non-runnable here. A parent importing NameEditor does not replace NameEditor’s own form dependency. Keep the correction small and remove any broad schema added solely to suppress this error.
import { Component } from "@angular/core";
import { FormControl, ReactiveFormsModule } from "@angular/forms";
@Component({
selector: "app-name-editor", standalone: true, imports: [ReactiveFormsModule],
template: `<label for="name">Name</label><input id="name" [formControl]="name">`
})
export class NameEditor { readonly name = new FormControl("Mira", { nonNullable: true }); }
In a valid component fixture the input starts with Mira and updates the control through the directive. Browser behavior is not claimed tested by this fragment.
Verify the model without overstating the result
The complete local program below uses the actual forms model under the pinned isolated packages. It confirms a value update, not that the template import repair rendered correctly. Keep that distinction: a successful control test can coexist with a missing directive in the application. Add an Angular component fixture that enters text through the labeled input and checks the model afterward when the runner is available.
import "@angular/compiler";
import { FormControl } from "@angular/forms";
const name = new FormControl("Mira", { nonNullable: true });
name.setValue("Lina");
console.log(name.value);
Lina
The program prints Lina. It does not compile NameEditor’s template or create a browser input.
Verify the fix
Run the local model with the pinned compiler and packages to confirm its exact output. Separately compile the corrected owner template in a complete Angular fixture and verify the NG8002 diagnostic is gone for the intended reason. Parser acceptance alone cannot resolve directive availability.
Exercise the rendered labeled input and assert the control receives its value. Retain an invalid-input and reset case where required. Do not describe the unexecuted component fragment as a browser test or use a real configured application to manufacture evidence.
Keep it from recurring
- Keep template dependencies with their standalone owner, distinguish providers from imports, and test reusable components through a host. Treat unknown bindings as useful evidence rather than automatically suppressing them.