Removing # from url in Angularjs while having .run in routes

Here is my app.js route file in AngularJS

var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'toaster']);
app.config(['$routeProvider',
    function ($routeProvider) {
        $routeProvider.
                when('/login', {
                    title: 'Login',
                    templateUrl: 'resources/views/layouts/loginUser.php',
                    controller: 'authCtrl'
                })
                .when('/', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/login.php',
                    controller: 'logoutCtrl'
                })
                .when('/reset', {
                    title: 'Reset Password',
                    templateUrl: 'resources/views/layouts/forgetPassword.php',
                    controller: 'authCtrl'
                })
                .when('/invalidtoken', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/invalidtoken.php',
                    controller: 'authCtrl',
                    role: '0'
                })

                //$locationProvider.html5Mode(true);
    }])


        .run(function ($rootScope, $location, Data, $http) {
            $rootScope.$on("$routeChangeStart", function (event, next, current) {
                     var nextUrl = next.$$route.originalPath;

                    if (nextUrl == '/signin' || nextUrl == '/login' || nextUrl == '/verify' || nextUrl == '/register' || nextUrl == '/registered' || nextUrl == '/reset' || nextUrl == '/resetdone' || nextUrl == '/registersuccess')
                    {
                        $location.path(nextUrl);
                    }
                     else
                    {   

                        $location.path('/');
                    }      
            });
        });

Here i use .run to handle few requests.

I want to remove the # from the url to make the url pretty,

So i did like this to remove the # as suggested here

app.config(['$routeProvider', '$locationProvider'
    function ($routeProvider, $locationProvider) {

and in the last line

$locationProvider.html5Mode(true);

But nothing is happening to the application, it stills haves # in the url.

Even i tried this way

How can i achieve this ?

Update :

If i do

.run(function ($rootScope, $location, Data, $http, $locationProvider) {

and in the last line

$locationProvider.html5Mode(true);

I am getting this error

Error: $injector:unpr
Unknown Provider

I have tried in many ways, but none of them working.

Update 2 :

Or can anyone suggest a link of angularjs example which provides example without # in url ?


Why do you want to use the .run() ? Add <base href="/" /> to you <head> or start of your body (first line) and then to match the logic of your .run() try this ( .otherwise("/path") to your $routeProvider):

var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'toaster']);
app.config(['$routeProvider', '$locationProvider',
    function ($routeProvider, $locationProvider) {
        $routeProvider.
                when('/login', {
                    title: 'Login',
                    templateUrl: 'resources/views/layouts/loginUser.php',
                    controller: 'authCtrl'
                })
                .when('/', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/login.php',
                    controller: 'logoutCtrl'
                })
                .when('/reset', {
                    title: 'Reset Password',
                    templateUrl: 'resources/views/layouts/forgetPassword.php',
                    controller: 'authCtrl'
                })
                .when('/invalidtoken', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/invalidtoken.php',
                    controller: 'authCtrl',
                    role: '0'
                })
. otherwise("/");
           $locationProvider.html5Mode(true);
    }]);

If you still face issues, I recommend https://github.com/angular-ui/ui-router

Update:

your index.html

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Green Hopping</title>
        <link rel="shotcut icon" type="favicon.ico" href="public/images/favicon.ico" />
        <link rel="icon" type="favicon.ico" href="public/images/favicon.ico" />
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
        <script src="https://code.angularjs.org/1.4.2/angular-route.min.js"></script>

    </head>
    <body ng-cloak="">
      <base href="/">
        <div data-ng-view="" id="ng-view" class="slide-animation"></div>
    </body>

    <script>
      var app = angular.module('myApp', ['ngRoute']);
        app.config(['$routeProvider', '$locationProvider',
            function ($routeProvider, $locationProvider) {
                $routeProvider.
                        when('/', {
                            title: 'Home',
                            templateUrl: 'home.html',
                            controller: 'homeCtrl'
                        })
                        .when('/login', {
                            title: 'Login',
                            templateUrl: 'login.html',
                            controller: 'authCtrl'
                        })
                        .when('/logout', {
                            title: 'Logout',
                            templateUrl: 'logout.html',
                            controller: 'logoutCtrl'
                        })
                        .when('/dashboard', {
                            title: 'Dashboard',
                            templateUrl: 'dashboard.html',
                            controller: 'dashboardCtrl'
                        })          
                        .otherwise('/');              
                        $locationProvider.html5Mode(true);
            }])
        .run(function ($rootScope, $location, $http, loginSrv) {
            $rootScope.$on("$routeChangeStart", function (event, next, current) {
                    var nextUrl = next.$$route.originalPath;
                    var orUseUrl = $location.path();
                    console.log(nextUrl);
                    if (nextUrl === '/logout'){loginSrv.logout();}
                    if (nextUrl === '/login'){loginSrv.login();}
                    if (loginSrv.loggedin === false) { $location.path('/'); } 
                    else { $location.path(nextUrl); }
            });
        });
        app.service("loginSrv",function(){
          var ls= this;
          ls.loggedin = false;
          ls.logout = function(){
            ls.loggedin = false;
          }
          ls.login = function(){
            ls.loggedin = true;
          }
        });
        app.controller("homeCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })     
        app.controller("dashboardCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })                    
        app.controller("authCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })
        app.controller("logoutCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })        
    </script>

</html>

All other templates are same like this. Copy paste the following for home.html , login.html , dashboard.html , logout.html . Plunker will not be able to show issues with routes for client side. Try this. This is completely functional code.

<div>
    <div><a href="/">Home</a> | 
    <a href="/login">Login</a> | 
    <a href="/dashboard">Dashboard</a> | 
    <a href="/logout">Logout</a></div>

    <div> This is from the home/login/dashboard/logout Controller. Loggedin: {{loggedin}}</div>
</div>

try changing:

$locationProvider.html5Mode(true);

To:

$locationProvider.html5Mode({
   enabled: true,
   requireBase: false
});

You can't inject $locationProvider in .run because providers are only available for .config

This answer should help but you will have 2 issues:

  1. You will need a check before $locationProvider.html5Mode(true) as it will not work on IE 10 or older.

    if(window.history && window.history.pushState){
        $locationProvider.html5Mode(true);
    } 
    
  2. This will work only by removing the # when the user enters it in the url, i.e. if the users types app/#/login it will change to app/login. However, if the user bookmarks or copies the changed url app/login and enters that in the browser he will get an error as the server does not know about angular routing since it is client side only. In the thread I linked above you may find some comments on how to fix this.


Are you by chance receiving a 404 error ? Whenever you change the mode to html5history you have to tell the web server to always return the index page no matter what URL is requested. As the angular docs says here: https://docs.angularjs.org/guide/$location

Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows Angular to differentiate between the part of the url that is the application base and the path that should be handled by the application.

Have you tried doing that and configured it properly ? Also remember that you have to specify the base entry href of your application for it to work like

  <base href="/" />