1
votes

The question is this. How can I return function(response) result to ngModel.$asyncValidators.usernameAvailable. The url specified in $http.get returns true if user exists and false if not. P.S. response.data returns the correct answer, I checked.

app.directive('usernameAvailableValidator',['$http', function($http){
    return{
        restrict : 'A',
        require : 'ngModel',
        link : function(scope, element, attrs, ngModel){
            ngModel.$asyncValidators.usernameAvailable =  function(username){
                return $http.get('/auth/username/exists/'+username).
                    then(function(response){return response.data});
            };
        }
    }
}])
2

2 Answers

3
votes

Asynchronous validators expects rejected promise in case of failed validation. It means that you need to reject your promise in case if user exists. In your case it's enough just to use $q.reject:

app.directive('usernameAvailableValidator', ['$q', '$http', function($q, $http) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            ngModel.$asyncValidators.usernameAvailable = function(username) {
                return $http.get('/auth/username/exists/' + username).
                then(function(response) {
                    if (response.data) return $q.reject();
                });
            };
        }
    }
}])
0
votes

You should dump the form properties. e.g.

<form name="fred" novalidate> 
    ...     
</form>

<div>{{ fred }}</div>

You should see a load of valid and invalid values. One should relate to usernameAvailable. In your asyncValidator you may need to use $q.resolve() and $q.reject() for valid and invalid.

Note you could rely on $http (and not use $q) since $http returns a promise but this only works if you want to resolve on 2xx responses and reject for all other responses, which doesn't seem to be the case here.

Also when rejecting the binding will fail unless you use ...

data-ng-model-options='{allowInvalid:true}'