version 2
version 2

Reputation: 1059

angularjs- Why http request returns false with resolve?

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?

Upvotes: 1

Views: 701

Answers (1)

hylimR
hylimR

Reputation: 393

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.

Upvotes: 3

Related Questions