简体   繁体   中英

Angular route resolution - deferred.reject not working - Angular 1 + TypeScript

Following is my route configuration

function routes($routeProvider: ng.route.IRouteProvider) {

        let accessResolver = ['UserFactory', (UserFactory: any) => {
            return UserFactory.isAuthenticated();
        }];

        //Configuring routes
        $routeProvider.when('/', {
            templateUrl: '/views/home.html',
            controller: 'HomeController',
            controllerAs: 'homeCtrl',
            resolve: accessResolver
        }).when('/login', {
            templateUrl: '/views/login.html',
            controller: 'LoginController',
            controllerAs: 'loginCtrl'
        }).otherwise({
            redirectTo: '/'
        });
    }

And my route change error handler

function run($rootScope: ng.IRootScopeService, $location: ng.ILocationService) {
        $rootScope.$on("$routeChangeError", () => {
            console.log("Route Change Error");
            $location.url('/login?redirect=' + $location.url());
        });
    }

And the UserFactory

module TheHub {
    export interface IUserFactory {
        isAuthenticated(): ng.IDeferred<String>;
    }

    class UserFactory implements IUserFactory {

        constructor(private $http: ng.IHttpService, private $q: ng.IQService, private $rootScope: any) {
        }

        isAuthenticated(): ng.IDeferred<String> {
            let deferred = this.$q.defer();
            if (this.$rootScope.auth && this.$rootScope.auth.isAuthenticationChecked) {
                if (this.$rootScope.auth.isAuthenticated) {
                    deferred.resolve('OK');
                } else {
                    deferred.reject('Unauthorized');
                }
            } else {
                this.$http.get('secure/user').then(
                    (response: ng.IHttpPromiseCallbackArg<{}>) => {
                        if (!this.$rootScope.auth) {
                            this.$rootScope.auth = {};
                        }
                        this.$rootScope.auth.isAuthenticationChecked = true;
                        this.$rootScope.auth.isAuthenticated = true;
                        deferred.resolve('OK');
                    },
                    (error: any) => {
                        if (!this.$rootScope.auth) {
                            this.$rootScope.auth = {};
                        }
                        this.$rootScope.auth.isAuthenticationChecked = true;
                        deferred.reject('Unauthorized');
                    });
            }
            return deferred;
        }
    }

    function userFactory($http: ng.IHttpService, $q: ng.IQService, $rootScope: any) {
        return new UserFactory($http, $q, $rootScope);
    }

    userFactory.$inject = ['$http', '$q', '$rootScope'];

    angular.module('TheHub').factory('UserFactory', userFactory);
}

The logic here is, I am firing a request to check if the user is already logged in and has a session. The problem is, when the user is not logged in already, the service is failing and the promise is getting rejected. But, I am not sure why, the handler $routeChangeError is not being fired. It is working fine when there is a JavaScript error.

You've forgotten the .promise so that you only returned the deferred, which was neither awaited nor the resolution value you expected.

But you should avoid the deferred antipattern anyway - just do

isAuthenticated(): ng.IPromise<String> {
    if (this.$rootScope.auth && this.$rootScope.auth.isAuthenticationChecked) {
        if (this.$rootScope.auth.isAuthenticated) {
            return this.$q.resolve('OK');
//          ^^^^^^^^^^^^^^^^^^^^^^
        } else {
            return this.$q.reject('Unauthorized');
//          ^^^^^^^^^^^^^^^^^^^^^^
        }
    } else {
        return this.$http.get('secure/user').then(
//      ^^^^^^
            (response: ng.IHttpPromiseCallbackArg<{}>) => {
                if (!this.$rootScope.auth) {
                    this.$rootScope.auth = {};
                }
                this.$rootScope.auth.isAuthenticationChecked = true;
                this.$rootScope.auth.isAuthenticated = true;
                return 'OK';
//              ^^^^^^
            },
            (error: any) => {
                if (!this.$rootScope.auth) {
                    this.$rootScope.auth = {};
                }
                this.$rootScope.auth.isAuthenticationChecked = true;
                return this.$q.reject('Unauthorized');
//              ^^^^^^^^^^^^^^^^^^^^^
            }
        );
    }
}

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