Success! I finally managed to make this work in my testing AngularJS application. The method I used was inspired by Ben Nadel's blog. I've included the entire controller code below:
Update: The key difference in this new approach lies in the order of operations within the function. The problem with the previous method was that Angular didn't have enough time to update before allowing the $location.path() to proceed, leading it to trigger an event listener still. By using stopWatchingLocation() to cancel that listener and giving Angular time to digest, we resolved this issue.
Essentially, the critical change was made in the proceedWithLocationChange function:
Execute this first: stopWatchingLocation();
then
$timeout(() => {$location.path( targetPath ).search( targetSearch ).hash( targetHash )},10);
}
This approach worked perfectly 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 );
}
}]);