For a project I'm working on, I've got a very simple dialog, to add a custom employee to a business application. The modal itself is nothing special - first name, last name, OK, Cancel. Easy...right?
One of the business rules, however, is that we disallow the submission of duplicate employees. To that end, I implemented the following angular directive:
(function() {
'use strict';
angular.module('app').directive('checkDuplicateEmployee', ['$q', 'officesSvc', 'webDataSvc', directive]);
function directive($q, officesSvc, webDataSvc) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, vm) {
vm.$asyncValidators.duplicateEmployee = function (modelValue, viewValue) {
// Problem visible here!
var args = {
officeType: officesSvc.officeType,
officeName: officesSvc.selectedOffice.name,
firstName: scope.vm.firstName,
lastName: scope.vm.lastName
};
// Custom wrapper for $http.
return webDataSvc.get('/api/admin/DoesEmployeeExist', args)
.then(function(results) {
if (results === true)
deferred.reject(results);
return true;
});
};
}
}
}
})();
The problem I'm encountering, is that when I add the directive to a input...
<input type="text" id="firstName" name="firstName"
maxlength="35"
ng-model="vm.firstName"
required check-duplicate-employee />
And I enter something, the state that gets sent to the server is the state immediately before my keypress.
Field: | vm.firstName:
----------------------------
T |
Te | T
Tes | Te
Test | Tes
As a result, I can reason from this that the scope doesn't get updated until after the validation runs.
Question: How can I do an asynchronous validation that operates after the $scope.vm
object has been updated? Bear in mind, I can't just pass the viewValue
to the firstName
property in the args list - I have this same validation on the inputs for the vm.firstName
and vm.lastName
properties!