Christophe L Christophe L - 9 months ago 39
AngularJS Question

Angular: how to handle both HTML5 mode routes and hash routes?

I've been using the "standard" routes in Angular 1 that use the

#
sign (e.g.
/app#/home
). Now I would like to switch to the HTML5 mode to have pretty URLs (e.g.:
/app/home
).

I've toggled the HTML5 mode with
$locationProvider.html5Mode(true)
and everything is working as expected.

However, some of our users may still have bookmarks and links in email that have the old URL format and those would break. I would like to have the old URLs still work (have
/app#/home
redirect to
/app/home
automatically).

I've tried having a default route that looks at the hash like so:

$routeProvider
.when({ ... })
.otherwise({
'controller': function($location) {
var hash = $location.hash();
// At this point the hash is undefined (even when there is one in the URL)
console.log('hash = ' + hash);
// if (hash && hash.indexOf('/') == 0) {
// $location.path(hash);
// } else {
// $location.path('/home')
// }
}
});


That unfortunately did not work (the controller doesn't see the hash and Angular seems to go in an infinite digest loop).

Any idea on how to achieve that?

Answer Source

Use $routeChangeStart :

 angular.module('routing', ['ngRoute'])
       .run(['$rootScope', '$location', '$window', function($rootScope, $location, $window) {
          $rootScope.$on("$routeChangeStart", 
            (event, current, previous, rejection) => {
              if (/#\//.test($window.location.hash)) {
                 $location.path($window.location.hash.replace('#', ''));
              }
          });

...