1

I have a login system...and I'm trying to implement login/logout feature to a website.

This is the fiddle I'm following- FIDDLE

This is my route file:

(function() {
  var onlyLoggedIn = function($location, $q, AuthService2) {
    var deferred = $q.defer();

    if (AuthService2.isLogin()) {
      deferred.resolve();
    } else {
      deferred.reject();
      $location.url('/login');
    }
    return deferred.promise;
  };

  angular.module('myApp', [
      'ngRoute',
      'myApp.login',
      'myApp.home',
      'myApp.logout',
      'myApp.notifications'
    ])
    .factory('AuthService2', ["$http", "$location", function($http, $location) {
      //var vm = this;
      var baseUrl = 'api/';

      return {

        isLogin: function() {
          var token;
          if (localStorage['entrp_token']) {
            token = JSON.parse(localStorage['entrp_token']);
          } else {
            token = "";
          }
          var data = {
            token: token
          };
          $http.post(baseUrl + 'validateUserToken', data).success(function(response) {
            if (response.msg == "authorized") {
              //console.log(response.msg);
              return localStorage.isLogged === "true";
            } else {
              return localStorage.isLogged === "false";
            }
          });
        }
      }
      return {
        isLogin: isLogin
      };
    }])

  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/login', {
        controller: 'LoginController',
        templateUrl: 'app/components/login/loginView.html',
        controllerAs: 'vm'
      })
      .when('/home', {
        controller: 'HomeController',
        templateUrl: 'app/components/home/homeView.html',
        resolve: {
          loggedIn: onlyLoggedIn
        },
        controllerAs: 'vm'
      })
      .when('/logout', {
        controller: 'LogoutController',
        templateUrl: 'app/components/login/loginView.html',
        resolve: {
          loggedIn: onlyLoggedIn
        },
        controllerAs: 'vm'
      })
      .when('/notifications', {
        controller: 'NotificationsController',
        templateUrl: 'app/components/notifications/notificationsView.html',
        resolve: {
          loggedIn: onlyLoggedIn
        },
        controllerAs: 'vm'
      })

    .otherwise({
      redirectTo: '/login'
    });
  }]);

})();

Users will be visiting login page. After authentication, I set a session and a local storage token.

I use resolve to check whether the user is valid or not. I defined a function for that (as you can see it from the code).

Upon login, I'm able to validate the user and set the session and login controller redirects the valid user to home. But the user reaches the route and he stays in login page itself.

My http request is fine. I checked it and it returns correct result. But I think the function returns false and afterthat only the http request is getting executed. because I can see the http request in consoel and it returns positive result, so the user should get navigated but it's not happening because http request is getting delayed or something.

I tried giving an alert message inside this if else,and it always goes to else condition, no matter what.

 if (AuthService2.isLogin()) {
      deferred.resolve();
    } else {
      deferred.reject();
      $location.url('/login');
    }

Why is it so? I'm pretty much new to ANgular. Is this a limitation of angular?

1
  • Reviewed example. First mistake is using if (Auth.isLogin()) when you rely on request that is actually promise and you are writing if instead of .then() for isLogin() check. Simply - you messed up async $http request for login with sync if in check login function. Commented Jul 18, 2016 at 11:25

1 Answer 1

3
+50

The problem is that there is no return statement in your isLogin function.

Your return statement is inside the $http.post callback NOT isLogin hence isLogin return undefined thus resolved to falsy.

$http.post(baseUrl + 'validateUserToken', data).success(function(response) {
        //Notice that you are inside function(response) closure.
        if (response.msg == "authorized") {
          return localStorage.isLogged === "true";
        } else {
          return localStorage.isLogged === "false";
        }
      });

I can suggest you to return $http.post instead, $http.post return a promise object which you can use in such way, below is an brief example on how you can do it.

isLogin: function() {
      //Omitted some code
      //This method return a promise object
      return $http.post(baseUrl + 'validateUserToken', data);
      });


AuthService2.isLogin().then(function(res){
    if (response.msg == "authorized") {
      deferred.resolve();
    } else {
      deferred.reject();
      $location.url('/login');
    }
}, errorCallback); //Optional if you want to handle when post request failed

Code is not tested, just to give you the idea.

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

5 Comments

Can you update the question or the fiddle with the above method? I fairly certain the method should work logic wise..
jsfiddle.net/pm1c3hok Check this fiddle. it mocks a login. after clicking login button, user can access about page..that's the logic..check console. @Harry Lim
Just return localStorage.isLogged from isLogin is already enough to know whether user is logged in ? If false then redirect to login page...I don't know what purpose $http.post serve here tbh.
In original post, $http is used to make a call..and check validity of user with backend data..@Harry Lim
That service fetches localstorage variable and validates it with database value... @Harry Lim

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.