This warning is emitted when ngModel (or any template-driven form control) is placed inside
a child component whose parent component hosts a form directive (NgForm or
FormGroupDirective), but the control cannot register with that form.
The root cause is that NgModel injects ControlContainer with @Host(), which stops the
injector from crossing component boundaries. The form directive in the parent component's
template is invisible to NgModel in the child's template.
As a result, the child's controls silently act as standalone — they do not participate in the parent form's value, validity, or submission state.
Fixing the warning
Option 1: Bridge the ControlContainer with viewProviders
Add viewProviders to the child component so it re-exports the parent form into its own view.
Use the same class that the warning names — NgForm for template-driven forms (<form>), or
FormGroupDirective for reactive forms ([formGroup]):
// Parent uses a template-driven form: <form> ... <app-child> </form>
import {ControlContainer, NgForm} from '@angular/forms';
@Component({
selector: 'app-child',
template: `<input name="email" [(ngModel)]="email" />`,
viewProviders: [{provide: ControlContainer, useExisting: NgForm}],
})
export class Child {
email = '';
}
// Parent uses a reactive form: <div [formGroup]="myGroup"> ... <app-child> </div>
import {ControlContainer, FormGroupDirective} from '@angular/forms';
@Component({
selector: 'app-child',
template: `<input name="email" [(ngModel)]="email" />`,
viewProviders: [{provide: ControlContainer, useExisting: FormGroupDirective}],
})
export class Child {
email = '';
}
The parent form then sees and validates the child's controls normally.
Option 2: Mark the control as standalone
If the child's controls should genuinely be independent of the parent form, opt out explicitly:
<input name="email" [(ngModel)]="email" [ngModelOptions]="{standalone: true}" />
Debugging the warning
The warning message includes the error code NG01354. Use the call stack to locate which
ngModel triggered it. Check whether the component that owns the <form> tag is the same
component that owns the ngModel input — if they differ, apply one of the options above.