1

I have the following code that calls an REST webservice. The web service returns a boolean.

    checkCurrentPassword: function (passwordInfo) {
        var valid = false;
        $http.post('/api/preference/password/check', passwordInfo)
            .success(function (data) {
                valid = data;
            });
        return valid;
    }

The trouble is that by the time the checkCurrentPassword returns valid is still false because the ajax call has not completed due to its asynchronous nature.

I am not sure how to make sure the valid variable is properly assigned the value returned from the server.

Can anyone please help?

edit 1:

Using a callback, It seems I am only deporting the problem to the controller layer... See below:

from angular service:

checkCurrentPassword: function (passwordInfo, callback) {
              return  $http.post('/api/preference/password/check', passwordInfo)
                    .success(function (data) {
                        callback(data);
                    });
            }

from angular controller:

 $scope.updatePassword = function () {
            if ($scope.updatePasswordForm.$valid) {

                var valid = false;

                passwordService.checkCurrentPassword({plainPassword: $scope.passwordInfo.currentPassword}, function(data, status){
                    valid = data;
                });

                console.log(valid);//always false

                passwordService.updatePassword($scope.passwordInfo, function (data, status) {
                    console.log('Updated password successfully');
                    $state.go('dashboard');
                });
            }
        };

edit 2: here is how I rewrote the controller:

$scope.updatePassword = function () {
            if ($scope.updatePasswordForm.$valid) {
                passwordService.checkCurrentPassword({plainPassword: $scope.passwordInfo.currentPassword}).success(function (data) {
                    if (data) {
                        passwordService.updatePassword($scope.passwordInfo, function (data, status) {
                            console.log('Updated password successfully');
                            $state.go('dashboard');
                        });
                    }
                });
            }
        };
3
  • Use a callback: .success(function (data) { myCallback(data); }); Commented Dec 16, 2014 at 14:36
  • Have a look at stackoverflow.com/a/13088385/783219 Commented Dec 16, 2014 at 14:45
  • Thanks all. I have edited my post accordingly. Commented Dec 16, 2014 at 14:54

3 Answers 3

1

You should return the promise (HttpPromise) returned by $http.get, see: https://docs.angularjs.org/api/ng/service/$q and https://docs.angularjs.org/api/ng/service/$http

This example may help you:

angular.module('app',[]);

angular.module('app').service('Foo',function($q){

  this.checkPassword = function(value){
    //replace this example code with a $http call
    console.log('checkPassword:',value);
    var deferred = $q.defer();
    setTimeout(function(){
      if(value && value.length >= 4){
        deferred.resolve(value);        
      } else {
        deferred.reject('oops invalid password!!!');
      }   
    },100);
    return deferred.promise;
  };

  this.updatePassword = function(value){
    //replace this example code with a $http call
    console.log('updatePassword:',value);
    var deferred = $q.defer();
    setTimeout(function(){
      if(Math.random() > 0.5){
        deferred.resolve('password updated');        
      } else {
        deferred.reject('error while updating password');
      }   
    },100);
    return deferred.promise;
  };

});

angular.module('app').run(function(Foo){

  Foo.checkPassword('tolkjlkj')
    .then(Foo.updatePassword)
    .then(function(result){
      console.log('Yes',result);
    }).catch(function(error){
      console.log('Oops',error);
    });

});
Sign up to request clarification or add additional context in comments.

2 Comments

The issue is that I need a plain boolean from the caller/client side.
@balteo - There is no way to accomplish that. You can't force an asynchronous operation to block and wait. You have to consume a promise, or use a callback.
1

You should use angulars's built in $q service

You're function would look something like this. (make sure to inject $q into your code at the top)

checkCurrentPassword: function (passwordInfo) {

    var deferred = $q.defer();
    var valid = false;

    $http.post('/api/preference/password/check', passwordInfo)
        .success(function(data){
            valid = data;
            deferred.resolve();
        })
        .error(function(error){
            deferred.reject();
        });

    return deferred.promise;

};

Comments

0

I think you could solve it with the callbacks...

checkCurrentPassword: function (passwordInfo) {

  $http.post('/api/preference/password/check', passwordInfo)
             .success(function (data) {
                 return data;
             }).error(function (data) {
                 return false;
             });

}

1 Comment

It seems you are returning data from the inner function. I need to return it from the outer function...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.