- 
                Notifications
    You must be signed in to change notification settings 
- Fork 27.3k
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>