Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS : Should service's boolean method return promise that resolves to true/false, or that gets resolved/rejected?

The patterns of promises usage still confuse me.

For example, in Angular application, I have a service usersService with method emailExists(email). Obviously, it performs request to the server to check whether given email already exists.

It feels natural for me to make the method emailExists(email) to return promise that in normal operation resolves to either true or false. If only we have some unexpected error (say, server returned 500: internal server error, then promise should be rejected, but in normal operation, it is resolved to corresponding boolean value.

Hovewer, when I started implementing my async validator directive (by $asyncValidators), I see that it wants resolved/rejected promise. So, by now, I ended up with this rather ugly code:

'use strict';

(function(){

   angular.module('users')
   .directive('emailExistsValidator', emailExistsValidator);


   emailExistsValidator.$inject = [ '$q', 'usersService' ];
   function emailExistsValidator($q, usersService){
      return {
         require: 'ngModel',
         link : function(scope, element, attrs, ngModel) {

            ngModel.$asyncValidators.emailExists = function(modelValue, viewValue){
               return usersService.emailExists(viewValue)
               .then(
                  function(email_exists) {
                     // instead of just returning !email_exists,
                     // we have to perform conversion from true/false
                     // to resolved/rejected promise
                     if (!email_exists){
                        //-- email does not exist, so, return resolved promise
                        return $q.when();
                     } else {
                        //-- email already exists, so, return rejected promise
                        return $q.reject();
                     }
                  }
               );
            };
         }
      }
   };

})();

It makes me think that I should modify my service so that it returns resolved/rejected promise instead. But, it feels a kind of unnatural for me: in my opinion, rejected promise means "we can't get result", not "negative result".

Or, do I misunderstand the promise usage?

Or, should I provide two methods? What is the common pattern to name them?

Any help is appreciated.

like image 444
Dmitry Frank Avatar asked Jul 29 '15 14:07

Dmitry Frank


1 Answers

In this case there is no correct/incorrect approach to this problem. What you are saying about your email check service sounds resonable: in fact, existence of the email in database is not strictly denotes a failure scenario, promise rejection usually corresponds to and reflects.

On the other hand, the way Angular implemented their async validators also makes sense, if you think about it. Failed validation result conceptually feels like a failure, not in terms of HTTP, but in sense of business logic.

So in this case I would probably go and adjust my custom service to at least return non-success status, like 409 Conflict.

If you still want to return 200 success code along with true/false resonses you can still make validator code a little bit less ugly:

ngModel.$asyncValidators.emailExists = function (modelValue, viewValue) {
    return usersService.emailExists(viewValue).then(function (email_exists) {
        return $q[email_exists ? 'when' : 'reject']();
    });
};
like image 153
dfsq Avatar answered Oct 06 '22 20:10

dfsq