First time calling, the authenticated property is false, even the credential is OK. If I login once again with the same credential, it will be OK.

Anyway, I am not sure that my factory below is the right way in angularjs or not. Would you please give me any suggestions?

Factory:

app.factory('authenticatorService',['$resource', function($resource){
    var authenticator = {};

    authenticator.attempt = function(email, password){
        var current = this;
        $resource("/service/authentication/:id",null,{'update' : { method: 'PUT'}})
            .save({'email' : email,'password': password},
                //success
                function(response){
                    current.authenticated = sessionStorage.authenticated = true;
                    current.userinfo = response.user;
                    current.authenticated = true;
                },
                function(response){
                    current.authenticated = false;
                }
            );
        return  this.authenticated;
    };
    authenticator.logout = function(){
        delete sessionStorage.authenticated;
        this.authenticated = false;
        this.userinfo = null;
        return true;
    };
    authenticator.check = function(){
        if(this.userinfo && this.authenticated){
            return true;
        }
        return false;
    };

    return authenticator;

}]);

Controller:

app.controller('authenCtrl',
[
'authenticatorService',
'$scope',
'$sanitize',
'$log',
'$location',
function(alert, authenticator, $scope, $sanitize, $log, $location){

    $scope.login = function(){

        if(authenticator.attempt($sanitize($scope.email) ,$sanitize($scope.password))){
            $location.path('/dashboard');
        }else{
            alert.add("danger","Login fail.");
        }
    }
}]);
有帮助吗?

解决方案

The this.authenticated in authenticator.attempt will return before the asynchronous call from $resource has completed.

You will need to wait for the promise to be resolved before returning from the factory, and before receiving in the controller.

Something like this should hopefully work:

Factory:

authenticator.attempt = function(email, password){

  var current = this;

  $resource("/service/authentication/:id", null, {'update' : { method: 'PUT'}})
    .save({'email' : email,'password': password},
      function(response){
          current.authenticated = sessionStorage.authenticated = true;
          current.userinfo = response.user;
          current.authenticated = true;
      },
      function(response){
          current.authenticated = false;
      }
    ).$promise.then(function () {
      return current.authenticated;
    });
};

Controller:

$scope.login = function() {

  var email = $sanitize($scope.email);
  var password = $sanitize($scope.password);

  authenticator.attempt(email, password).then(function(isAuthenticated) {

    if (isAuthenticated) $location.path('/dashboard');
    else alert.add("danger", "Login fail.");

  });
};
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top