Pregunta

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.");
        }
    }
}]);
¿Fue útil?

Solución

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.");

  });
};
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top