I want to show a confirmation popup(with Yes & No buttons) when there is a route change in my angularJs App.
I tried this way. This event is called each time before the route change, But this function is not restricting the user from going to a different route, even when the user has selected 'NO'
$scope.$on('$locationChangeStart', function (event) {
if (vm.counterObject.myList.length > 0) {
var answer = confirm("Are you sure?")
if (answer) {
event.preventDefault();
}
}
});
Any suggestion on where am I wrong?
Finally got this working in my test angularjs app. This is an approach I adapted from Ben Nadel's site. I decided to just paste the whole controller here
Edit: What is different from the last approach is the OOO (order of operations) in this function. The issue was angular didn't get a chance to $digest
the update in time when we are allowing the $location.path()
to go through. It was still hitting the event listener. stopWatchingLocation()
cancels that listener but due to the wiring of events, we have to allow angular to digest that.
So essentially, this made the difference in the proceedWithLocationChange
function:
Running this first: stopWatchingLocation();
then
$timeout(() => {$location.path( targetPath ).search( targetSearch ).hash( targetHash )},10);
}
it worked great in my environment
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', '$location', '$timeout', function($scope, $location, $timeout) {
$scope.currentLocation = $location.url();
$scope.myList = [1,2,3]
$scope.$on(
"$locationChangeSuccess",
function handleLocationChangeSuccessEvent( event ) {
$scope.currentLocation = $location.url();
}
);
var startWatchingTimer = $timeout( startWatchingForLocationChanges, 0, false );
var stopWatchingLocation = null;
function handleLocationChangeStartEvent( event ) {
event.preventDefault();
var targetPath = $location.path();
var targetSearch = $location.search();
var targetHash = $location.hash();
if ($scope.myList.length > 0) {
if (confirm('Leave the page?')) {
proceedWithLocationChange(targetPath, targetSearch, targetHash)
}
} else {
proceedWithLocationChange(targetPath, targetSearch, targetHash)
}
}
function proceedWithLocationChange(targetPath, targetSearch, targetHash) {
stopWatchingLocation();
$timeout(() => {$location.path( targetPath ).search( targetSearch ).hash( targetHash )},10);
}
function startWatchingForLocationChanges() {
console.log("watching");
stopWatchingLocation = $scope.$on( "$locationChangeStart", handleLocationChangeStartEvent );
}
}]);