Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Controller not waiting for a service return value in a conditional statement

Tags:

angularjs

I'm currently trying to redirect logged-in users away from the login page if they try to access it in the app. The controller associated with the login page - Login_controller calls a function in an authorisation service - Authorisation_service.isLoggedIn(). If this service returns true, the user should be redirected to the logged-in overview page.

By logging to the console I can see that before the service has returned true, the conditional statement has already declared that the returned value from the service is undefined. After which the service does return true, but it is too late.

How do I get the controller's conditional statement to wait for the return value from the service?

Authorise_service.js

myApp.factory('Authorise', ['User', '$http', '$location', '$rootScope', function( User, $http, $location, $rootScope ) {
    return {
        isLoggedIn: function() {
            if( ((sessionStorage.username && sessionStorage.authKey) && (sessionStorage.username !== "null" && sessionStorage.authKey !== "null")) || ((localStorage.username && localStorage.authKey) && (localStorage.username !== "null" && localStorage.authKey !== "null" )) ) {
                if( sessionStorage.username ) {
                    var usernameLocal = sessionStorage.username;
                    var authKeyLocal = sessionStorage.authKey;
                } else {
                    var usernameLocal = localStorage.username;
                    var authKeyLocal = localStorage.authKey;
                }
                //pass to server
                var user = User.query({ usernameLocal: usernameLocal, authKeyLocal: authKeyLocal }, function(user) {
                    if( user.loginSuccess === 1 ) {
                        return true;
                    } else {
                        return false;
                    }
                });
            } else {
                return false;
            }
        }
    };
}]);

Login_controller.js

myApp.controller( 'Login_controller', function( Authorise, $scope, $location ) {
    if( Authorise.isLoggedIn() === true ) {
        console.log("Authorise.isLoggedIn() = true");
        $location.path('/teach/overview');
    }
});
like image 810
Fisu Avatar asked Feb 18 '23 06:02

Fisu


1 Answers

Smk is right. You are probably trying to rely on the data that hasn't been yet returned by the server. "Yet" is the key issue here, because most probably your data is properly fetched from the server, you are simply trying to refer to the results before they are ready! To check if this is the truth, simply add console.log(user) in User.query(...) callback.

Smk pointed you to the right approach - use PROMISE API instead. Basically, promise is an object that you can further use to do some actions when the results are ready from the server. To illustrate this:

function myFunc() {
   var result = false;

   // You are calling async request to the server, so the execution won't wait for the
   // results. It will simply fire server request and proceed to next lines.
   serverCall(function(srvResponse){

      result = srvResponse.everythingIsGood; // This will be called after the whole method finishes!
   });

   return result; // This will MOST PROBABLY return 'false' all the times.
}

And a proper way of doing this:

function theRealLogicYouWantToDo(result) {
   if (result) {
      // ...
   } else {
      // ...
   }
}

serverCall(function(srvResponse) {
   theRealLogicYouWantToDo(srvResposne.everythingIsGood);
});

This is nice tutorial about all this in JQUERY. It's not only used for server calls, but in few other places in JS as well. Good to learn it.

like image 112
ŁukaszBachman Avatar answered Jun 04 '23 12:06

ŁukaszBachman