Angularjs - Cancel Route Change Event

AngularJs - cancel route change event

Instead of $routeChangeStart use $locationChangeStart

Here's the discussion about it from the angularjs guys: https://github.com/angular/angular.js/issues/2109

Edit 3/6/2018 You can find it in the docs: https://docs.angularjs.org/api/ng/service/$location#event-$locationChangeStart

Example:

$scope.$on('$locationChangeStart', function(event, next, current) {
if ($scope.form.$invalid) {
event.preventDefault();
}
});

AngularJS - Detecting, stalling, and cancelling route changes

You are listening to the wrong event, I did a bit of googling but couldn't find anything in the docs. A quick test of this:

$scope.$on("$locationChangeStart", function(event){
event.preventDefault();
})

In a global controller prevented the location from changing.

AngularJs : Cancel route resolve without promise

The problem is that I don't want to use $location.path() in the case of login fail, because it reloads the whole page while I simply need to stay on the route and simply cancel the route, as long as user login is wrong.

To cancel a route change from a resolver function, use a throw statement:

monApp.config(function ($routeProvider, $locationProvider){

var rsf = { // This function tells if user is logged or not
"check":function(stockeUtilisateur,$location,Notification){
u = stockeUtilisateur.getUtilisateur();

if(u.role=='admin'||u.role=='utilisateur'){
Notification.success("Youre logged");
}
else{
//$location.path('/accueil');
//Notification.error("bad password");
throw "bad bassword";
}
}
};

$routeProvider
.when('/accueil', {
templateUrl: 'vues/accueil.html',
controller: 'neutreCtrl'
})
.when('/compte', {
templateUrl: 'vues/compte.html',
controller: 'compteCtrl',
resolve:rsf
})

.otherwise({redirectTo: '/accueil'});
})

When a resolver function throws an error, the route change is prevented and a $routeChangeError event is broadcast.

How to watch for a route change in AngularJS?

Note: This is a proper answer for a legacy version of AngularJS. See this question for updated versions.

$scope.$on('$routeChangeStart', function($event, next, current) { 
// ... you could trigger something here ...
});

The following events are also available (their callback functions take different arguments):

  • $routeChangeSuccess
  • $routeChangeError
  • $routeUpdate - if reloadOnSearch property has been set to false

See the $route docs.

There are two other undocumented events:

  • $locationChangeStart
  • $locationChangeSuccess

See What's the difference between $locationChangeSuccess and $locationChangeStart?

Detect route change in an Angular service

By using $routeChangeStart, you are listening to a broadcast sent by $routeProvider on every change of the route. I don't think you need to call it in multiple places ( controllers ), just to check this.

In your service:

angular.module('lmsApp')
.service('pageAuth', ['$location', function ($location) {
var canAccess = function(event,next,current){

var user = firebase.auth().currentUser;
//requireAuth is a custom route property
if (next.$$route.requireAuth && user == null ) {

event.preventDefault(); //prevents route change
alert("You must be logged in to access page!");

}
else {
console.log("allowed");
}

}

$rootScope.$on('$routeChangeStart',canAccess);
}]);

And then inject your service in the .run() part of your application. This will ensure the check will be done automatically ( by the broadcast as mentioned earlier ).

In you config part :

angular.module('lmsApp')
.run(function runApp(pageAuth){
//rest of your stuff
});

Route change events while trying to avoid using $rootScope

You missread that.
First of all, this event was added by Angular team - do you think they recommend not to use it?:D That article is about that you should not put everything to $rootScope, which seems to be an easy way for beginners.

Actually, using $rootScope - for for global events is absolutely ok -- that is actual purpose of this service.

AngularJS confirm before route change

Demo: http://plnkr.co/edit/Aq8uYg

In the demo, if you change the value of input, you will be noticed when trying to go back.

Listen to $locationChangeStart and use event.preventDefault() to cancel the location change if changes not confirmed.

This method has one advantage over $route.reload(): current controller and models will not be re-instantiated. thus all of your variables are kept the same as user click the "Back" button.



Related Topics



Leave a reply



Submit