title: AngularJs with hash in href breaks scrolling and transforms url to hash+fwslash+id
body: <p><strong>How to configure AngularJs to scroll to anchor element specified in href with an #id?</strong></p>
  
  <h1>The problem</h1>
  
  <p>The anchor link with a hash, ex. href="#recommanded" becomes url#/recommanded instead of url#recommanded so it will not scroll as expected. If angularjs library is not loaded, it works fine.
  In the statusbar when I move the cursor on top of the link the browser's statusbar correctly displays the link I'm about to be heading, but after clicking it will get transformed and will not scroll correctly.
  I'm not using angular's routes.</p>
  
  <p>Snippets from my AngularJS code that might be interfering with scrolling / js location manipulations:</p>
  
  <pre><code>...
  app.config([ '$httpProvider', '$compileProvider', function($httpProvider, $compileProvider) {
      $compileProvider.debugInfoEnabled(false);
      // Initialize get if not there
      if (!$httpProvider.defaults.headers.get) {
          $httpProvider.defaults.headers.get = {};
      }
  
      // Disable IE ajax request caching
      $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
  } ]);
  ...
  app.directive('jumpForm', function($timeout) {
      return {
          restrict : 'A',
          link : function(scope, elem) {
  
              // set up event handler on the form element
              elem.on('submit', function() {
                  $timeout(function() {
                      // find the first invalid element
                      var firstInvalid = elem[0].querySelector('.has-error');
  
                      // if we find one, set focus
                      if (firstInvalid) {
  
                          $('html, body').animate({
                              duration : 2000,
                              scrollTop : (firstInvalid.offsetTop + 100)
                          });
                      }
                  }, 200);
  
              });
          }
      };
  });
  ...
  app.factory('httpResponseInterceptor', [ '$q', '$location', '$window', function($q, $location, $window) {
      return {
          response : function(response) {
              if (response &amp;&amp; response.data &amp;&amp; response.data.errorCode == 'AUTHENTICATION_REQUIRED') {
                  var _context = $("body").attr("data-context");
                  var redirectUrl = _context + '/registration?msg=session_expired';
                  $window.location.href = redirectUrl;
                  return $q.reject(response);
              }
              return response;
          }
      }
  } ]);
  
  app.config([ '$httpProvider', function($httpProvider) {
      $httpProvider.interceptors.push('httpResponseInterceptor');
  } ]);
  </code></pre>
  
  <p>A call with hashtag:</p>
  
  <pre><code>&lt;a href="#recommanded"&gt; &lt;/a&gt;
  </code></pre>
  
  <h1>Trials and errors</h1>
  
  <h2>Internal workarounds</h2>
  
  <h3>anchorScroll</h3>
  
  <p>In the thread <a href="https://stackoverflow.com/questions/14712223/how-to-handle-anchor-hash-linking-in-angularjs?rq=1">How to handle anchor hash linking in AngularJS</a> it is advised to insert this snippet:</p>
  
  <pre><code>app.controller('TestCtrl', function($scope, $location, $anchorScroll) {
      $scope.scrollTo = function(id) {
          $location.hash(id);
          $anchorScroll();
      }
  });
  </code></pre>
  
  <p>And in calling it:</p>
  
  <pre><code>&lt;a ng-click="scrollTo('recommanded')"&gt;Foo&lt;/a&gt;
  </code></pre>
  
  <p>This results in no error on the console but just the same behavior as before. Url is transformed no scrolling to anchor. Also I don't like the idea to end up having an ng-click function for this.</p>
  
  <p>Appended my angularjs with:</p>
  
  <pre><code>app.run(function($rootScope, $location, $anchorScroll) {
      //when the route is changed scroll to the proper element.
      $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) 
      {
          if($location.hash()) $anchorScroll();  
      });
  });
  </code></pre>
  
  <p>and called it as</p>
  
  <pre><code>&lt;a href="#/test#recommanded"&gt;Test/Foo&lt;/a&gt;
  </code></pre>
  
  <p>Resulted in no error but scroll not working neither.</p>
  
  <p>Some are hinting to just do a #/#recommanded in href. Use target="_self". None of them worked out for me.</p>
  
  <h2>External workaround solutions</h2>
  
  <h3>Directive scrollTo</h3>
  
  <pre><code>   app.directive('scrollto',
     function ($anchorScroll,$location) {
          return {
              link: function (scope, element, attrs) {
                  element.click(function (e) {
                      e.preventDefault();
                      $location.hash(attrs["scrollto"]);
                      $anchorScroll();
                  });
              }
          };
  })
  </code></pre>
  
  <p>The html is looking like:</p>
  
  <pre><code>&lt;a href="" scrollTo="recommanded"&gt;link&lt;/a&gt;
  </code></pre>
  
  <p>This one actually works, but would prefer a solution where the call href="#recommended" just works. Or at least animate the scroll.</p>
  
  <h3>angular-scroll's du-smooth-scroll</h3>
  
  <p>Added <a href="https://github.com/oblador/angular-scroll" rel="nofollow noreferrer">duScroll</a> to my angularApp.js: <code>var app = angular.module('app', [ ..., 'duScroll' ]);</code>
  I have the angular-scroll.min.js file loaded on the page with angularApp.js without error.
  I call <code>&lt;a du-smooth-scroll href="#recommended-to-you"&gt;recommanded&lt;/a&gt;</code> for an existing div with that id. But it wont do anything, no js errors but will not move.
  Tried duScroll module with adding explicit ease duration etc. settings, no errors but not working.</p>