简体   繁体   中英

AngularJS - Waiting for an asynchronous call

I'm starting to learn AngularJS and so far so good but I am currently stuck on a small issue about an synchronous function.

I would like the function AuthenticationSharedService.login() to be called and returned before executing the rest of the code. How can I do that?

app.js

myApp.config(['$routeProvider', '$httpProvider', 'USER_ROLES',
    function ($routeProvider, $httpProvider, USER_ROLES) {
        $routeProvider
            .when('/login', {
                templateUrl: 'views/login.html',
                controller: 'LoginController',
                access: {
                    authorizedRoles: [USER_ROLES.all]
                }
            })
            .when('/error', {
                templateUrl: 'views/error.html',
                access: {
                    authorizedRoles: [USER_ROLES.all]
                }
            })
            .otherwise({
                templateUrl: 'views/main.html',
                controller: 'MainController',
                access: {
                    authorizedRoles: [USER_ROLES.user]
                }
            });
    }])
    .run(['$rootScope', '$location', 'AuthenticationSharedService', 'Session', 'USER_ROLES',
        function($rootScope, $location, AuthenticationSharedService, Session, USER_ROLES) {
            $rootScope.$on('$routeChangeStart', function (event, next) {

                <!-- Bit of code to execute before going further -->
                if (!Session.login) {
                    console.log('First attempt to login');
                    AuthenticationSharedService.login();
                }
                <!-- /////////////////////////////////////////// -->

                if (AuthenticationSharedService.isAuthenticated()) {
                    // user is not allowed
                    $rootScope.$broadcast("event:auth-notAuthorized");
                } else {
                    // user is not logged in
                    $rootScope.$broadcast("event:auth-loginRequired");
                }
            });
        }]);

authenticationSharedService.js

myApp.factory('AuthenticationSharedService', ['$rootScope', '$http', '$cookieStore', 'authService', 'Session', 'Account',
    function ($rootScope, $http, $cookieStore, authService, Session, Account) {
        return {
            login: function () {
                return Account.get(function(data) {
                    Session.create(data.login, data.roles);
                    authService.loginConfirmed(data);
                });
            }
        };
    }]);

You need to use resolve. See http://docs.angularjs.org/api/ngRoute/provider/ $routeProvider or http://www.bfcamara.com/post/66001429506/authentication-in-a-spa-with-angular - this second link is quite good.

Resolve is a map of dependencies that should be injected into the controller. If any of the mapped objects are functions, the functions will be evaluated and their return values injected. If a function returns a promises, the view will not be rendered until the promise is resolved.

Just FYI, the view will not be rendered at all if the promise is rejected. You would want to deal with that situation in $rootScope.$on('routeChangeError', functionToHandleRejection)

Here's an example that should work for you:

.when('someUrl', {
  resolve: {
    object: function(AuthenticationSharedService) {
      return AuthenticationSharedService.login();
    }
  }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM