Recently I experienced a problem when I inherited a single page app that was using anchor tags on the home page to jump down to a specific location on the page. Recall that anchor tags can be used to jump to a spot on the page by first setting up an anchor name where you want to jump to:

<a name="anchor"></a>

And then an anchor tag which when clicked will jump to the location where the a name was set

<a href="#anchor">Link Text</a>

The template had an About section and a Team link in the navigation (shown below) which would jump down to the appropriate section when clicked.

Everything was fine until I added another html template that represented a new route, to go to a Profile page. The html looked something like this:

<ul class="nav navbar-nav">
	<li><a href="#about">About</a></li>
    <li><a href="#team">Team</a></li>
    <li ng-hide="!isLoggedIn()"><a href="/profile" >Profile</a></li>
</ul>

This looks like fairly run-of-the-mill html code except for the ng-hide="!isLoggedIn()" which essentially checks if the user is logged in and will only present the Profile link if the user is logged in.

From the home page, clicking on the About, Team, or Profile links worked fine. However, when I navigated to the Profile page and then clicked on the About or Team link, it simple took the URL and appended a #team or #about to it like so profile#team. Obviously this was not the intended behaviour so I did a little research and came up with this solution.

The html code is changed to the following where we use the ng-click action to accomplish the goal.

<div class="navbar-right">
  <ul class="nav navbar-nav">
    <li><a href="" ng-click="linkTo('/#about')">About</a></li>
    <li><a href="" ng-click="linkTo('/#team')">Team</a></li>
    <li ng-hide="!isLoggedIn()"><a href="/profile" >Profile</a></li>
  </ul>
</div>

The ng-click=linkTo(...) references the linkTo method that is defined in the controller, in this case a navigation controller I have created. The code looks like this:

angular.module('myAppName')
 .controller('NavbarCtrl', ['$scope', '$location', 'Auth', 
   function ($scope, $location, Auth) {
   //Do things here like check authentication

   //Redirect to the new location regardless of if it has anchor name
   $scope.linkTo = function(id) {
     $location.url(id);
   };
 }]);

The controller makes use of Angular's $location service which parses the URL in the browser address bar and makes it avalable to the application. It is two-way so changes to the address bar URL are reflected in the service and vice versa. Now when we click the links in the menu, they will redirect correctly.