AngularJS - Need some combination of $routeChangeStart and $locationChangeStart
One approach that comes to mind is trying to use the resolve parameter for this:
var resolver = function(access) { return { load: function($q) { if (access) { // fire $routeChangeSuccess var deferred = $q.defer(); deferred.resolve(); return deferred.promise; } else { // fire $routeChangeError return $q.reject("/login"); } } }}$routeProvider. when('/login', { controller: 'LoginCtrl', templateUrl: '/app/partial/login.html', resolve: resolver(false)}). when('/home', { controller: 'HomeCtrl', templateUrl: '/app/partial/home.html', resolve: resolver(true)}). otherwise({ redirectTo: '/login' });
Please note that I haven't tested the code above but I'm doing similar stuff in my projects.
I faced the same situation myself and my solution was aligned with what the OP intended to do.
I use the $locationChangeStart
event and the $route
service. By accessing $route.routes
, I get a hold of all route objects defined with $routeProvider
.
.run(function($rootScope, $route, $location) { $rootScope.$on('$locationChangeStart', function(ev, next, current) { // We need the path component of `next`. We can either process `next` and // spit out its path component, or simply use $location.path(). I go with // the latter. var nextPath = $location.path(); var nextRoute = $route.routes[nextPath] console.log(nextRoute.access); // There you go! });})
To parse the path component out of an absolute URL:
var urlParsingNode = document.createElement('a');urlParsingNode.href = next; // say, next = 'http://www.abc.com/foo?name=joeconsole.log(urlParsingNode.pathname) // returns "/foo"
Since version 1.3.0 you can actually use the newly introduced preventDefault-method. With that you can cancel the current route change and then apply your own custom redirect as shown in this github-issue:
$rootScope.$on("$routeChangeStart", function (event, next, current) { if (next.access) { event.preventDefault(); $rootScope.$evalAsync(function() { $location.path('/login'); }); }});
I implemented this method in my own project and it works perfectly. Hope it helps anyone else who stumbles across it.