Here's my code in the service.

this.loginUser = function(checkUser) {
    Parse.User.logIn(checkUser.username, checkUser.password, {
        success: function(user) {
            $rootScope.$apply(function (){
                $rootScope.currentUser = user;
            });
        }
    });
};

Here's my code in the controller:

$scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser);
        console.log($scope.currentUser)
};

So, what I want to do is, execute some code AFTER the completion of AJAX call, whose success function sets the value of $scope.currentUser, which, I can use for some conditional logic (like redirecting etc) The success function is correctly setting the value, but the console.log should be executed AFTER the execution of authenticationService.loginUser() function.

有帮助吗?

解决方案

You need to return a promise using $q and act on that.

For instance in your service:

this.loginUser = function(checkUser) {
    var deferred = $q.defer();
    Parse.User.logIn(checkUser.username, checkUser.password, {
        success: function(user) {
            $rootScope.$apply(function (){
                $rootScope.currentUser = user;
            });
            deferred.resolve();
        }
    });
    return deferred.promise;
};

Then in your controller act on the success:

$scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser).then(function() {
        console.log($rootScope.currentUser));
    });
};

其他提示

Try using $rootScope.$broadcast in your service then listen for it in your controller:

Service

Parse.User.logIn(checkUser.username, checkUser.password, {
    success: function(user) {
        $rootScope.$apply(function (){
            $rootScope.currentUser = user;
            $rootScope.$broadcast('user.online');
        });
    }
});

Controller

$scope.$on('user.online',function(){
    [ DO STUFF HERE ]
});

This isn't the best way to do this though @comradburk's use of $q is probably a better way.

If your application wait for external result, you should use $q for return a promise. If you are using angular-route or ui-router components, you can use resolve param for this. Take a look ngRoute documentation. In there has a example based in resolve param.

https://docs.angularjs.org/api/ngRoute/service/$route

i think you have two options here

  1. as answered by comradburk, use promises:

in Services:

this.loginUser = function(checkUser) {
var deferred = $q.defer();
Parse.User.logIn(checkUser.username, checkUser.password, {
    success: function(user) {
        deferred.resolve(user);
    }
});
return deferred.promise;

};

in controller:

$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser).then(function(user) {
    $scope.currentUser = user;
});
};
  1. using resolve, resolve your service at route level (...or state level in case you are using ui-router) before controller initialization and insert it as a dependency - helpful in scenarios like user authentication where you dont want user to be able to navigate further if authentication fails. from docs https://docs.angularjs.org/api/ngRoute/service/$route

YOMS (Yet One More Solution):

    this.loginUser = function(checkUser, onSuccess) {
        Parse.User.logIn(checkUser.username, checkUser.password, {
            success: function(user) {
                $rootScope.$apply(function() {
                    $rootScope.currentUser = user;
                    if (typeof onSuccess == 'function') onSuccess(user); // optionally pass data back
                });
            }
        });
    };

    $scope.logIn = function(user, function(returnedUser) {
    // console.log(returnedUser); // Optional, The returned user
        console.log($scope.currentUser)
    }) {
        authenticationService.loginUser($scope.checkUser);
    };
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top