user142617
user142617

Reputation: 386

asyncvalidator promise not being resolved

I am trying to cancel an $asyncValidator promise but I am an error of undefined is being thrown, here is my code:

(function () {
    'use strict';

angular
    .module("webclient.common.directives")
    .directive("duplicateModelNameValidator",
                ["$q",
                 "modelManager",
                 duplicateModelNameValidator
                ]);

function duplicateModelNameValidator($q, modelManager) {
    return {
        restrict: "A",
        require: "ngModel",
        link: function (scope, element, attrs, ngModel) {
            var classId = attrs.duplicateModelNameValidator;

            ngModel.$asyncValidators.duplicateModelName = function (modelValue) {
                var defer = $q.defer();
                //if the user hasn't touched the input box I don't want to call the database code
                if (ngModel.$pristine)
                    //I want to resolve the promise but get the error below?
                    return defer.resolve();

                modelManager.find(modelValue, false).then(function (data) {
                    if (data.exists === true)
                        // Found a row
                        return defer.reject();
                    else
                        // Did not find a row
                        return defer.resolve();
                });

                return defer.promise;
            }
        }
    }
}
}());

The code throws the error:

[ngModel:nopromise] Expected asynchronous validator to return a promise but got 'undefined' instead.

Thanks

Upvotes: 0

Views: 279

Answers (1)

Alexander Kravets
Alexander Kravets

Reputation: 4395

The methods defer.resolve() and defer.reject() control the state of the defer.promise, they do NOT return the promise, whereas validator function is expected to return the promise. You should use the methods $q.when() and $q.reject() instead:

ngModel.$asyncValidators.duplicateModelName = function (modelValue) {
    //if the user hasn't touched the input box I don't want to call the database code
    if (ngModel.$pristine) {
        return $q.when(true);
    }

    return modelManager.find(modelValue, false)
        .then(function (data) {
            if (data.exists === true) {
                // Found a row
                // this will reject the promise returned by modelManager.find()
                return $q.reject('exists');                 
            }

            // Did not find a row
            // no need to do anything, this promise is already 
            // resolved which will succeed the validation
        });
}

Upvotes: 3

Related Questions