Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return error context information from an AngularJS async validator?

I'm using the new AngularJS async validators feature introduced in 1.3. I have a directive that looks like this:

angular.module('app')
    .directive('usernameValidator', function(API_ENDPOINT, $http, $q, _) {
        return {
            require: 'ngModel',
            link: function($scope, element, attrs, ngModel) {
                ngModel.$asyncValidators.username = function(username) {
                    return $http.get(API_ENDPOINT.user, {userName: username})
                        .then(function(response) {
                            var username = response.data;
                            if (_.isEmpty(username)) {
                                return true;
                            } else {
                                return $q.reject(username.error);
                            }
                        }, function() {
                            return $q.reject();
                        });
                };
            }
        };
    });

I'd like to somehow get the value of username.error into the model controller scope so I can display it to the user. Displaying a static message is easy, however I want to display some of the error context information returned by the server as well.

Is there a clean way to do this or am I stuck with setting properties on the model controller?

Edit: To clarify, I am not looking for a one-off solution that just works. I intend to use this directive as a reusable, cleanly encapsulated component. This means directly writing to the surrounding scope or anything like that is probably not acceptable.

like image 581
Jannik Jochem Avatar asked Sep 15 '25 16:09

Jannik Jochem


1 Answers

the validation directive is just like any other directive, you have access to $scope, so why not set the value as it: $scope.errors.username = username.error;

angular.module('app')
    .directive('usernameValidator', function(API_ENDPOINT, $http, $q, _) {
        return {
            require: 'ngModel',
            link: function($scope, element, attrs, ngModel) {

                $scope.errors = $scope.errors | {}; //initialize it

                ngModel.$asyncValidators.username = function(username) {
                    return $http.get(API_ENDPOINT.user, {userName: username})
                        .then(function(response) {
                            var username = response.data;
                            if (_.isEmpty(username)) {
                                return true;
                            } else {
                                $scope.errors.username = username.error; //set it here
                                return $q.reject(username.error);
                            }
                        }, function() {
                            return $q.reject();
                        });
                };
            }
        };
    });

I just initialized it separately $scope.errors = $scope.errors | {}; //initialize it so that you can reuse $scope.errors object in multiple directives if you wish it

like image 126
harishr Avatar answered Sep 17 '25 06:09

harishr