AngularJS | handle routing before they load
.when('/', { templateUrl: 'src/app/views/index.html', controller: 'indexCtrl', resolve: function($q, $location) { var deferred = $q.defer(); deferred.resolve(); if (!isAuthenticated) { $location.path('/login'); } return deferred.promise; }})
My solution was combining $locationChangeStart
and $routeChangeStart
:
$rootScope.$on('$locationChangeStart', function (event) { //If login data not available, make sure we request for it if($facebook.isConnected()==null) { $facebook.getLoginStatus(); event.preventDefault(); return; } var next=parseRoute().$$route; if(!Auth.loginCheck(next)) event.preventDefault();});
I copied parseRoute()
from angular-route.js
to parse the given URL to route..
Then I build my login check handler(Auth.loginCheck
) in a way that if it fail it return false.
I also use $routeChangeStart
to handle $route.reload()
events, so now after every change within my authentication status I just do $route.reload()
:
$rootScope.$on('$routeChangeStart', function (event, next) { Auth.loginCheck(next);});
Finally I just make sure that this custom service is always will run by using simple run()
method.
Edit:
We now using ngAuth, a module we designed to solve that exact problem(based on the answer I gave here before).
At last, we developed a angular-module that solved this issue.. This module is based on the answer I published here before.
Due the requests here, we published a beta release that works now: http://github.com/GoDisco/ngAuth
Feel free to use it.
Angularjs resolve example:
.when('/profile', { templateUrl: 'views/profile.html', controller: 'ProfileCtrl', resolve: { app: function($q, $rootScope, $location) { var defer = $q.defer(); if ($rootScope.currentUser == undefined) { $location.path('/login'); }; defer.resolve(); return defer.promise; } }