Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS location.path() changes URL briefly, then reverts

I'm having a frustrating morning.

I have an app that has a base location, so in the head is <base href="/my/path/fruits/index.html" />. I'm trying to setup paging via a function nextPage(). When I hit the link that triggers nextPage(), I use $location.path('/page/:page').

Expected behaviour: The browser location url should change to http://localhost/my/path/fruits/page/2.

Actual behaviour: The browser URL changes (very briefly) to http://localhost/my/path/fruits/page/2 and then reverts back to http://localhost/my/path/fruits/.

Note: This behaviour doesn't seem to happen if I'm not using a base location. However, I need to use the base location because the app is sitting in a sub/sub/sub directory of the server.

Also: This behaviour doesn't happen if I set $locationProvider.html5Mode(false).

Am I doing something wrong? Is this a bug in Angular? Any help is greatly appreciated.

Here are the appropriate files.

index.html:

<!doctype html>
<html ng-app="fruits">
  <head>
    <base href="/my/path/fruits/index.html" />
    <script src="angular.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="MainCntl">
      <div ng-view></div>
    </div>
  </body>
</html>

script.js:

angular.module('fruits', [], function($routeProvider, $locationProvider) {
    $routeProvider
    .when('/', {
        templateUrl: 'fruits.html',
        controller: FruitCntl,
    })
    .when('/page/:page', {
        templateUrl: 'fruits.html',
        controller: FruitCntl,
    })
    .otherwise({redirectTo:'/'})
    ;

    // configure html5 
    $locationProvider.html5Mode(true).hashPrefix('!');
}).filter('startFrom', function() 
    {
        return function(input, start) 
        {
            start = +start; //parse to int
            if (input == undefined){
                input = [];
            }
            return input.slice(start);
        }
})
;

function MainCntl($scope,$location){
    angular.extend($scope,{
        current_page: 1,
        per_page: 3,
        fruits: [
            {name: 'Apples', color: 'red'},
            {name: 'Bananas', color: 'yellow'},
            {name: 'Oranges', color: 'orange'},
            {name: 'Grapes', color: 'purple'},
            {name: 'Blueberries', color: 'blue'},
            {name: 'Strawberries', color: 'red'},
            {name: 'Raspberries', color: 'red'},
            {name: 'Clementines', color: 'orange'},
            {name: 'Pears', color: 'green'},
            {name: 'Mangoes', color: 'orange'}
        ],

        nextPage: function(){
            this.current_page++;
            $location.path('/page/'+this.current_page);
        },

        previousPage: function(){
            this.current_page--;
            $location.path('/page/'+this.current_page);
        }
    })
    $scope.total_pages = Math.ceil($scope.fruits.length / $scope.per_page);
}

function FruitCntl($scope,$location,$routeParams){
    if ($routeParams.page != undefined){
        $scope.current_page = $routeParams.page;
    }
}

fruits.html (the view)

Page: <a ng-click="previousPage()" ng-show="current_page > 1">Previous</a> {{current_page}} of {{total_pages}} <a ng-click="nextPage()" ng-show="current_page < total_pages">Next</a>
<div ng-repeat="fruit in fruits | startFrom:(current_page - 1)*per_page | limitTo:per_page">
    {{fruit.name}} are {{fruit.color}}<br/>
</div>
like image 582
Trevor Mills Avatar asked Nov 22 '12 16:11

Trevor Mills


1 Answers

I had the same problem and couldn't for the life of me figure out what went wrong. What worked for me was changing the anchor tag which had the ng-click event attached to a button tag instead. From what I can gather Angular modifies the behavior of anchor tags when no href attribute is given to prevent the default action, so this might interfere if you update the location manually in a ng-click event handler. That's only my guess though, so hopefully someone will be able to explain better.

like image 117
fnakstad Avatar answered Sep 23 '22 06:09

fnakstad