1

This question comes from another one: AngularJS - Determine if the view should be displayed by an ajax call result upon the route changes

As to my previous question, finally I came to this solution:

(function() {
    'use strict';

    angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
        .config(routeConfigurator);

    angular.module("appClubS")
        .controller("checkLoginCtrl", checkLoginController);

    checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
    routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];

    function routeConfigurator($routeProvider, $locationProvider) {
        $routeProvider.when("/home", {
            templateUrl: "views/index.html"
        });

        // ...


        // the routes that visitor cannot access before signing in 
        $routeProvider.when("/account-profile/my-redeem", {
            templateUrl: "views/member_zone/my.redeem.html",
            resolve: {
                loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
                    var deferred = $q.defer();
                    var logStatus = userFactory.loggedin();
                    if (logStatus) {
                        deferred.resolve({
                            message: "Proceed to change route."
                        });
                    }
                    else {
                        deferred.reject({
                            message: "Redirect to the default page."
                        });
                        alert("Please Login First!");
                        $location.path("/login");
                    }
                    return deferred.promise;
                }]
            }
        });

        $routeProvider.when("/account-profile/my-survey", {
            templateUrl: "views/member_zone/my.survey.html",
            resolve: {
                loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
                    var deferred = $q.defer();
                    var logStatus = userFactory.loggedin();
                    if (logStatus) {
                        deferred.resolve({
                            message: "Proceed to change route."
                        });
                    }
                    else {
                        deferred.reject({
                            message: "Redirect to the default page."
                        });
                        alert("Please Login First!");
                        $location.path("/login");
                    }
                    return deferred.promise;
                }]
            }
        });

        // ...

    }


})();

However, I have repeated the same piece of code for each route I would like to forbid undesired access. So now my question is how to do it once for all. I have tried the code as below:

(function() {
    'use strict';

    angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
        .config(routeConfigurator);

    angular.module("appClubS")
        .controller("checkLoginCtrl", checkLoginController);

    checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
    routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];

    function routeConfigurator($routeProvider, $locationProvider) {
        $routeProvider.when("/home", {
            templateUrl: "views/index.html"
        });

        // ...


        // the routes that visitor cannot access before signing in 
        $routeProvider.when("/account-profile/my-redeem", {
            templateUrl: "views/member_zone/my.redeem.html",
            resolve: {
                loggedin: ["$q", "userFactory", "$location", checkPermit]
            }
        });

        $routeProvider.when("/account-profile/my-survey", {
            templateUrl: "views/member_zone/my.survey.html",
            resolve: {
                loggedin: ["$q", "userFactory", "$location", checkPermit]
            }
        });

        // ...

    }

    function checkPermit($q, userFactory, $location) {
        var deferred = $q.defer();
        var logStatus = userFactory.loggedin();
        if (logStatus) {
            deferred.resolve({
                message: "Proceed to change route."
            });
        }
        else {
            deferred.reject({
                message: "Redirect to the default page."
            });
            alert("Please Login First!");
            $location.path("/login");
        }
        return deferred.promise;
    }


})();

And it doesn't work, I got error saying: defer is not defined, something like that. Then I used a factory to wrap that piece of logic:

(function() {
    'use strict';

    angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
        .config(routeConfigurator);

    angular.module("appClubS")
        .controller("checkLoginCtrl", checkLoginController)
        .factory('checkPermit', checkPermitFactory);

    checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
    routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];
    checkPermitFactory.$inject = ['$q', '$location', 'userFactory'];

    function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
        $routeProvider.when("/home", {
            templateUrl: "views/index.html"
        });

        // ...


        // the routes that visitor cannot access before signing in 
        $routeProvider.when("/account-profile/my-redeem", {
            templateUrl: "views/member_zone/my.redeem.html",
            resolve: {
                loggedin: function (checkPermit) {
                    return checkPermit.checklogin();
                }
            }
        });

        $routeProvider.when("/account-profile/my-survey", {
            templateUrl: "views/member_zone/my.survey.html",
            resolve: {
                loggedin: function (checkPermit) {
                    return checkPermit.checklogin();
                }
            }
        });

        // ...

    }

    function checkPermitFactory($q, userFactory, $location) {

        function checklogin() {
            var deferred = $q.defer();
            var logStatus = userFactory.loggedin();
            if (logStatus) {
                deferred.resolve({ message: "Proceed to change route." });
            }
            else {
                deferred.reject({ message: "Redirect to the default page." });
                alert("Please Login First!");
                $location.path("/login");
            }

            return deferred.promise;
        }

        var factory = {
            checklogin: checklogin
        };

        return factory;
    }



})();

And I got error saying that it could not find checkPermit provider, when investigating this problem, I realized that you just cannot inject an dependency on an stance of factory to routeConfigurator, so here I am supposed to use checkPermitProvider instead.

I am confused now.

Any help is appreciated. Thanks.

Community
  • 1
  • 1
VincentZHANG
  • 745
  • 1
  • 13
  • 29

1 Answers1

0

thank you all for the replies.

In the end, I found I can get it working in this way:

(function() {
    'use strict';

    angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
        .config(routeConfigurator);

    angular.module("appClubS")
        .controller("checkLoginCtrl", ['$q', '$location', 'userFactory', function checkPermitFactory($q, userFactory, $location) {

        function checklogin() {
            var deferred = $q.defer();
            var logStatus = userFactory.loggedin();
            if (logStatus) {
                deferred.resolve({ message: "Proceed to change route." });
            }
            else {
                deferred.reject({ message: "Redirect to the default page." });
                alert("Please Login First!");
                $location.path("/login");
            }

            return deferred.promise;
        }

        var factory = {
            checklogin: checklogin
        };

        return factory;
    }])
        .factory('checkPermit', checkPermitFactory);

    checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
    routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];

    function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
        $routeProvider.when("/home", {
            templateUrl: "views/index.html"
        });

        // ...


        // the routes that visitor cannot access before signing in 
        $routeProvider.when("/account-profile/my-redeem", {
            templateUrl: "views/member_zone/my.redeem.html",
            resolve: {
                loggedin: function (checkPermit) {
                    return checkPermit.checklogin();
                }
            }
        });

        $routeProvider.when("/account-profile/my-survey", {
            templateUrl: "views/member_zone/my.survey.html",
            resolve: {
                loggedin: function (checkPermit) {
                    return checkPermit.checklogin();
                }
            }
        });

        // ...

    }

})();

I used $inject property to specify the dependencies just because that was suggested in the section 'Manually Identify Dependencies' in this article: https://github.com/johnpapa/angularjs-styleguide#manually-identify-dependencies.

And honestly I don't quite understand how does $inject work exactly though; I just got the concerns behind that. So this problem has been solved, but I don't know the difference between the two ways of defining a controller and declaring there dependencies.

VincentZHANG
  • 745
  • 1
  • 13
  • 29