Md. Al-Amin
Md. Al-Amin

Reputation: 1441

Refactor angular ui-router resolver to use it globally

I have resolve method inside angular config. It was written to protect the view from unauthorized access. Now the problem is, if I create a different route file, I have to copy the same resolve on each file. Is there any other way so that I can write it once and use it everywhere?

(function(){

'use strict';

var app = angular.module('app');

app.config(/* @ngInject */ function($stateProvider, $urlRouterProvider) {

    var authenticated = ['$q', 'MeHelper', '$state', function ($q, MeHelper, $state) {
        var deferred = $q.defer();
        MeHelper.ready()
            .then(function (me) {
                if (me.isAuthenticated()) {
                    deferred.resolve();
                } else {
                    deferred.reject();
                    $state.go('login');
                }
            });
        return deferred.promise;
    }];

    $stateProvider
        .state('index', {
            url: "",
            views: {
                "FullContentView": { templateUrl: "start.html" }
            }
        })
        .state('dashboard', {
             url: "/dashboard",
             views: {
                 "FullContentView": { templateUrl: "dashboard/dashboard.html" }
             },
             resolve: {
                 authenticated: authenticated
             }
         })
        $urlRouterProvider.otherwise('/404');

     });

})();

Edit: MeHelper is a Service.

Upvotes: 1

Views: 61

Answers (2)

Sravan
Sravan

Reputation: 18647

To refactor your code, you should register a service and take the authentication code to the service.

Authenticate service:

app.factory('authenticateService', ['$q', 'MeHelper',
    function($q,MeHelper){

        var obj = {};

        obj.check_authentication = function(params)
        {
            var deferred = $q.defer();
            MeHelper.ready()
                .then(function (me) {
                    if (me.isAuthenticated()) {
                        deferred.resolve();
                    } else {
                        deferred.reject();
                        $state.go('login');
                    }
                });
            return deferred.promise;

        }


        return obj;
    }
]);

Then, use this service in any route file in resolve, taking this service name in dependency injection or the function parameter,

Route configuration file:

(function(){

'use strict';

var app = angular.module('app');

app.config(/* @ngInject */ function($stateProvider, $urlRouterProvider) {


   $stateProvider
        .state('index', {
            url: "",
            views: {
                "FullContentView": { templateUrl: "start.html" }
            }
        })
        .state('dashboard', {
             url: "/dashboard",
             views: {
                 "FullContentView": { templateUrl: "dashboard/dashboard.html" }
             },
             resolve: {
                 authenticated: 
                        function(authenticateService) {
                                return authenticateService.check_authentication();
                        }
             }
         })
        $urlRouterProvider.otherwise('/404');

     });


})();

watch the below lines, this is what we changes in the route configuration to resolve.

the service is injected in below lines:

resolve: {
             authenticated: 
                function(authenticateService) {
                             return authenticateService.check_authentication();
                   }
         }

Upvotes: 3

Adrian Brand
Adrian Brand

Reputation: 21638

Do your check on route change.

app.run(function ($rootScope, $state) {
      $rootScope.$on('$locationChangeSuccess', function () {
        if (unauthorized && $state.current.name !== 'login') {
          $state.go('login');
        }
      });
  });

Upvotes: 0

Related Questions