0

I am trying synchronize two call backs one from service and one directly called . (This is old code so please ignore code quality)

 if($scope.newUser.password == $scope.newUser.password2)
        {
            // search for the user to see if it already exists
            UserValidateService.findUserByEmail($scope.newUser.username, $scope.newUser.email, function(user){
                console.log(user);
                if(user[0]) {
                    alert('email Id already exists ******');
                    return false;
                }
            }).then(function(){ 
                $http.get("/api/user/"+$scope.newUser.username)
                .success(function(newUser) {
                    // if user does not exist, create it new
                    if(newUser.length == 0) {
                        $http.post("/api/user", $scope.newUser)
                        .success(function(newUser){
                            if(newUser == null)
                                alert("Unable to register user");
                            else
                                $location.path( $scope.newUser.username+"/home" );
                        });
                    }
                    else
                    {
                        alert("User already exists");
                    }
                });
            });
        }
        else
        {
            alert("Passwords must match. Try again");
        }

Service :

app.factory('UserValidateService', function($http){

    var findUserByEmail = function (user, email, callback) {
        $http.get("/api/user/"+user+"/email/"+email)
        .success(callback);
    };

    return {
        findUserByEmail: findUserByEmail
    };
});

Error:

TypeError: Cannot read property 'then' of undefined
    at h.$scope.register (user.js:118)
    at angular.js:10567
    at angular.js:18627
    at h.$eval (angular.js:12412)
    at h.$apply (angular.js:12510)
    at HTMLButtonElement.<anonymous> (angular.js:18626)
    at HTMLButtonElement.jQuery.event.dispatch (jquery.js:5095)
    at HTMLButtonElement.elemData.handle (jquery.js:4766)

Can any please let me where I am going wrong or how to make this code synchronize i.e calling

user2936008
  • 1,317
  • 5
  • 19
  • 42
  • Does UserValidateService.findUserByEmail() returns promise? – Satoshi Mar 12 '16 at 02:30
  • its a callback function : edited question with the service code. – user2936008 Mar 12 '16 at 03:20
  • if you're trying to synchronize then I would suggest deferring using $q. Create two promises and then synchronize with $q.all. I found a jfiddle someone made which could serve as an example: https://jsfiddle.net/ThomasBurleson/QqKuk/ – DanielC Mar 12 '16 at 04:18
  • just to fix the error, you need to return the promise from service. Other than this, still don't understand what you mean by 'synchronize two callbacks' – sdfacre Mar 12 '16 at 05:33

1 Answers1

0

Your UserValidateService doesn't return a promise, it uses a callback from the $http success method. This is an anti-pattern that should be avoided.

Convert your factory to return the promise from the $http service:

app.factory('UserValidateService', function($http){

    var findUserByEmail = function (user, email) {
        return $http.get("/api/user/"+user+"/email/"+email)
    };

    return {
        findUserByEmail: findUserByEmail
    };
});

Then use the .then method of the promise to execute the callback functionality.

var promise = UserValidateService
                  .findUserByEmail($scope.newUser.username,
                                   $scope.newUser.email);

var derivedPromise = promise.then ( function(response){
    console.log(response.user);
    if(response.user[0]) {
        alert('email Id already exists ******');
    });
    //return response for chaining
    return response;
});

Subsequent actions can chain off the derivedPromise.

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95