angular $location,$route lifecycle events fired off twice when browser automatically encodes url #8368
Description
issue observed in latest legacy(1.2.21) and beta
versions(1.3.0-beta.17
I provided a simplified example that demonstrates the issue I am encountering below
Basically, the behavior that I am seeing and trying to prevent, is that when my app loads a route whose url is
automatically encoded by the browser (e.g. because there are spaces or +'s in the parameter values), I am seeing the $location and $route service lifecycle events
getting fired off twice.
Using the example provided below the easiest way to duplicate this behavior is to load the app and append the following params:
?message=test val
?message=test+val
If you look at the console output you'll see the first example causes the $locationChangeStart and $locationChangeSuccess handler to be fired off twice.
Based on the documentation I believe angular is monitoring the address bar for changes and I am guessing its firing off these events for the unencoded url and then again
once its encoded.
Is this a bug? Is there a way to prevent this?
NOTE: I also noticed that despite a '+' being a valid substitute for a space in a parameter value, the resulting value retains the '+'; i.e. ?message=test+val will be rendered as 'test+val' not 'test val'. There is an existing ticket for this issue.
<!DOCTYPE html>
<html id="ng-app" data-ng-app="test">
<head>
<script src="angular.js"></script>
<script src="angular-route.js"></script>
<script>
'use strict';
angular.module('test', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider.when('/',
{
template: '{{data.params}}',
controller:'TestCtrl',
resolve:{params: function($route) {return $route.current.params;}}
})
})
.run(function($rootScope) {
$rootScope.$on('$locationChangeStart',function(event, next, current){
console.log(event.name,'current=' + current,'next=' + next);
});
$rootScope.$on('$locationChangeSuccess',function(event, next, current){
console.log(event.name,'current=' + current,'next=' + next,'\n');
});
})
.controller('TestCtrl',function($scope,params){
console.log('Inside TestCtrl');
$scope.data={params:params};});
</script>
</head>
<body>
<div ng-view></div>
</body>
</html>