In Angular, ng-model is commonly used for two-way data binding in forms. However, sometimes form validation does not work as expected. Below, I will explain why this happens and how to fix it step by step.
1. Understanding ng-model in Angular
ng-model is mainly used in template-driven forms (not reactive forms). Example:
<form #myForm="ngForm">
<input type="text" name="username" ngModel required>
<div *ngIf="myForm.controls.username?.invalid && myForm.controls.username?.touched">
Username is required!
</div>
<button [disabled]="myForm.invalid">Submit</button>
</form>
Here, validation should work. If not, check the following issues.
2. Common Reasons for ng-model Validation Not Working
1. Missing name Attribute
Angular uses the name attribute to track form controls. If it’s missing, validation won’t work.
Incorrect:
<input type="text" ngModel required>
Fix: Add name
<input type="text" name="username" ngModel required>
2. Forgot to Add FormsModule in app.module.ts
Angular needs FormsModule for ng-model to work properly.
If FormsModule is Missing
import { NgModule } from '@angular/core';
@NgModule({
imports: [
// FormsModule is missing
]
})
export class AppModule { }
Fix: Import FormsModule
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule // Add this
]
})
export class AppModule { }
3. Not Using #formVariable="ngForm" for Form Validation
Angular tracks form validity using ngForm, which needs a reference.
Incorrect:
<form>
<input type="email" name="email" ngModel required>
<div *ngIf="email.invalid">Invalid Email</div>
</form>
email.invalid will not work because the form is not referenced.
Fix: Add #myForm="ngForm"
<form #myForm="ngForm">
<input type="email" name="email" ngModel required #email="ngModel">
<div *ngIf="email.invalid && email.touched">Invalid Email</div>
</form>
Now, email.invalid works properly.
4. Using ng-model in Reactive Forms (Incorrect Usage)
ng-model is used for template-driven forms, not reactive forms.
Incorrect:
<form [formGroup]="userForm">
<input type="text" ngModel formControlName="username">
</form>
Using both ngModel and formControlName together is not allowed in Angular.
Fix: Remove ngModel in Reactive Forms
<form [formGroup]="userForm">
<input type="text" formControlName="username">
</form>
5. Incorrect Condition for Validation Message
Sometimes, the validation message does not appear because the condition is wrong.
Incorrect:
<div *ngIf="username.invalid">
Username is required!
</div>
Fix: Use touched or dirty to show messages after user interaction
<div *ngIf="username.invalid && username.touched">
Username is required!
</div>
6. No Validation Styles (User Doesn’t See Error)
Sometimes validation works, but the user doesn’t notice the error.
Fix: Add Styling
input.ng-invalid.ng-touched {
border: 2px solid red;
}
7. Button Not Disabled When Form is Invalid
If the submit button is not disabling correctly, check the [disabled] binding.
Fix: Disable Button When Form is Invalid
<button [disabled]="myForm.invalid">Submit</button>
3. Full Working Example
<form #myForm="ngForm">
<label>Username:</label>
<input type="text" name="username" ngModel required #username="ngModel">
<div *ngIf="username.invalid && username.touched">
Username is required!
</div>
<label>Email:</label>
<input type="email" name="email" ngModel required #email="ngModel">
<div *ngIf="email.invalid && email.touched">
Invalid Email!
</div>
<button [disabled]="myForm.invalid">Submit</button>
</form>
Now, form validation works properly!
