This is another case where a custom directive is your friend. You’ll want to create a directive and inject $http or $resource into it to make a call back to the server while you’re validating.
Some pseudo code for the custom directive:
app.directive('uniqueEmail', function($http) {
var toId;
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
//when the scope changes, check the email.
scope.$watch(attr.ngModel, function(value) {
// if there was a previous attempt, stop it.
if(toId) clearTimeout(toId);
// start a new attempt with a delay to keep it from
// getting too "chatty".
toId = setTimeout(function(){
// call to some API that returns { isValid: true } or { isValid: false }
$http.get('/Is/My/EmailValid?email=" + value).success(function(data) {
//set the validity of the field
ctrl.$setValidity("uniqueEmail', data.isValid);
});
}, 200);
})
}
}
});
And here’s how you’d use it in the mark up:
<input type="email" ng-model="userEmail" name="userEmail" required unique-email/>
<span ng-show="myFormName.userEmail.$error.uniqueEmail">Email is not unique.</span>
EDIT: a small explanation of what’s happening above.
- When you update the value in the input, it updates the $scope.userEmail
- The directive has a $watch on $scope.userEmail it set up in it’s linking function.
- When the $watch is triggered it makes a call to the server via $http ajax call, passing the email
- The server would check the email address and return a simple response like ‘{ isValid: true }
- that response is used to $setValidity of the control.
- There is a in the markup with ng-show set to only show when the uniqueEmail validity state is false.
… to the user that means:
- Type the email.
- slight pause.
- “Email is not unique” message displays “real time” if the email isn’t unique.
EDIT2: This is also allow you to use form.$invalid to disable your submit button.