ng-required Validation Not Working – Step-by-Step Fix
If ng-required
validation is not working in AngularJS, it is usually due to:
- Incorrect binding (
ng-model
missing or incorrect) - Form controller not initialized correctly
novalidate
missing in<form>
tag (for HTML5 conflict)- CSS hiding validation messages
- Using
ng-required
inside a condition that does not apply immediately
Step 1: Basic Working Example of ng-required
Before debugging, ensure you’re using ng-required
correctly.
Correct Example: Required Input Validation
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ng-required Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body ng-controller="myController">
<form name="myForm" novalidate>
<label>Email:</label>
<input type="email" name="email" ng-model="user.email" ng-required="true">
<span class="error" ng-show="myForm.email.$error.required && myForm.email.$touched">
Email is required!
</span>
<br><br>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
<script>
var app = angular.module("myApp", []);
app.controller("myController", function ($scope) {
$scope.user = {};
});
</script>
<style>
.error {
color: red;
}
</style>
</body>
</html>
Why This Works?
novalidate
prevents HTML5 validation from interfering.ng-model="user.email"
ensures two-way binding.ng-show="myForm.email.$error.required && myForm.email.$touched"
ensures errors appear only when input is touched.
Step 2: Common Reasons ng-required
Fails & Fixes
Issue 1: ng-model
Missing or Incorrect
Fix: Ensure ng-model
is present
<input type="text" name="username" ng-model="user.username" ng-required="true">
Why?
AngularJS tracks form fields via ng-model
. Without it, validation won’t work.
Issue 2: novalidate
Not Used in <form>
Fix: Add novalidate
in the form tag
<form name="myForm" novalidate>
Why?
Prevents browser’s default validation from interfering with Angular’s validation system.
Issue 3: Validation Message Not Displaying
Fix: Use $error.required
with $touched
or $dirty
<span class="error" ng-show="myForm.username.$error.required && myForm.username.$touched">
Username is required!
</span>
Why?
$error.required
checks if the field is empty.$touched
ensures message appears only after user interacts.
Issue 4: ng-required
in ng-if
Blocks (Not Rendered Initially)
Fix: Use ng-show
Instead of ng-if
<input type="text" name="username" ng-model="user.username" ng-required="showRequired">
Why?
ng-if
removes elements from the DOM, causing Angular validation to break.ng-show
only hides the element while keeping validation intact.
Issue 5: Button Not Disabling on Invalid Form
Fix: Use ng-disabled="myForm.$invalid"
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
Why?
This ensures the button remains disabled until the form is valid.
Issue 6: ng-required
With Dynamic Conditions Not Working
Fix: Use ng-required="someCondition"
Correctly
<input type="text" name="username" ng-model="user.username" ng-required="isRequired">
$scope.isRequired = true;
Why?
If ng-required="true"
is used inside a condition that’s initially false
, it won’t work.
Step 3: Final Working Example With All Fixes
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ng-required Fixed</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body ng-controller="myController">
<form name="myForm" novalidate>
<label>Username:</label>
<input type="text" name="username" ng-model="user.username" ng-required="isRequired">
<span class="error" ng-show="myForm.username.$error.required && myForm.username.$touched">
Username is required!
</span>
<br><br>
<label>Email:</label>
<input type="email" name="email" ng-model="user.email" ng-required="true">
<span class="error" ng-show="myForm.email.$error.required && myForm.email.$touched">
Email is required!
</span>
<br><br>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
<script>
var app = angular.module("myApp", []);
app.controller("myController", function ($scope) {
$scope.user = {};
$scope.isRequired = true;
});
</script>
<style>
.error {
color: red;
}
</style>
</body>
</html>
🔹 Why This Works?
- Uses
ng-required
properly with dynamic values. - Prevents
ng-if
issues. - Disables submit button when the form is invalid.