Redirecting to a certain route based on condition
After some diving through some documentation and source code, I think I got it working. Perhaps this will be useful for someone else?
I added the following to my module configuration:
angular.module(...)
.config( ['$routeProvider', function($routeProvider) {...}] )
.run( function($rootScope, $location) {
// register listener to watch route changes
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
if ( $rootScope.loggedUser == null ) {
// no logged user, we should be going to #login
if ( next.templateUrl != "partials/login.html" ) {
// not going to #login, we should redirect now
$location.path( "/login" );
}
}
});
})
The one thing that seems odd is that I had to test the partial name (login.html
) because the "next" Route object did not have a url or something else. Maybe there's a better way?
I have been trying to do the same. Came up with another simpler solution after working with a colleague. I have a watch set up on $location.path()
. That does the trick. I am just starting to learn AngularJS and find this to be more cleaner and readable.
$scope.$watch(function() { return $location.path(); }, function(newValue, oldValue){
if ($scope.loggedIn == false && newValue != '/login'){
$location.path('/login');
}
});
Here is maybe a more elegant and flexible solution with 'resolve' configuration property and 'promises' enabling eventual data loading on routing and routing rules depending on data.
You specify a function in 'resolve' in routing config and in the function load and check data, do all redirects. If you need to load data, you return a promise, if you need to do redirect - reject promise before that. All details can be found on $routerProvider and $q documentation pages.
'use strict';
var app = angular.module('app', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "login.html",
controller: LoginController
})
.when('/private', {
templateUrl: "private.html",
controller: PrivateController,
resolve: {
factory: checkRouting
}
})
.when('/private/anotherpage', {
templateUrl:"another-private.html",
controller: AnotherPriveController,
resolve: {
factory: checkRouting
}
})
.otherwise({ redirectTo: '/' });
}]);
var checkRouting= function ($q, $rootScope, $location) {
if ($rootScope.userProfile) {
return true;
} else {
var deferred = $q.defer();
$http.post("/loadUserProfile", { userToken: "blah" })
.success(function (response) {
$rootScope.userProfile = response.userProfile;
deferred.resolve(true);
})
.error(function () {
deferred.reject();
$location.path("/");
});
return deferred.promise;
}
};
For russian-speaking folks there is a post on habr "Вариант условного раутинга в AngularJS."