Search code examples
javascriptangularjsresolve

Angular resolve is rejected, but page is still loading


This resolve function works everywhere else, and I'm stumped as to why the profile page is still executing when the promise is rejected. We produced this bug by logging in, deleting the token from storage and then trying to navigate to the profile page. It goes through all the authentication steps, and logs out. It hits the redirection line, but then it still loads the profile page, throwing errors because the auth has been cleared.

Any help you can offer would be great. Let me know if you need more info.

app.config('$routeProvider')

.when('/profile', {
    templateUrl: '/templates/profile.html',
    controller: 'ProfileController',
    resolve: {
        auth: function (SessionService) {
            SessionService.resolve()
        }
    }
}).
otherwise({
    redirectTo: '/login'
})

function resolve () {
    if (self.isAuthenticated()) {
        return $q.when({auth: true})
    } else {
        $q.reject({auth: false})
            self.logout() // first we go here
        }   
    }
}

function logout () {
    var auth = self.storage()
    if (...) {
       ...
    } else {
        self.clearUserAuthentication() // then here
        $location.path('/login') // it redirects here, but still initializes the profile controller
    }
}

Solution

  • /profile route always resolves because auth always returns resolved promise (or better put it: it doesn't return rejected promise and doesn't throw exception). Correct code would be:

    .when('/profile', {
        templateUrl: '/templates/profile.html',
        controller: 'ProfileController',
        resolve: {
            auth: function (SessionService) {
                return SessionService.resolve()
            }
        }
    }).
    

    Note, that it's very important that auth handler returns promise. If you omit return keyword it results into implicit return undefined. This is meaningless but is still considered as resolved promise.