angularjsnode.jsurl-routingangular-routinghtml5mode

How to give priority to angular routing instead of node routing while using html5Mode(true) in angular JS


I want to route my application according to angular routes in html5mode(true). Here is my angular code snippet.

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>MyApp</title>
        <base href="/">
        <!-- Import Angular -->
        <script type="text/javascript" src="bower_components/angular/angular.min.js"></script>
        <!-- Import Angular Route -->
        <script type="text/javascript" src="bower_components/angular-route/angular-route.min.js"></script>
        <!-- Import Local JS Files -->
        <script type="text/javascript" src="app/app.routes.js"></script>
        <script type="text/javascript" src="app/userController.js"></script>
        <script type="text/javascript" src="app/app.js"></script>
    </head>
    <body>
        <ng-view ng-app="myApp"></ng-view>
    </body>
</html>

app.js

var app = angular.module('myApp', ['appRoute'])

app.routes.js

angular.module('appRoute', ['ngRoute', 'userController'])

.config(function($routeProvider, $locationProvider) {
    $locationProvider.html5Mode({
        enabled: true
    });
    $routeProvider
    .when('/user', {
        templateUrl: 'app/user.html',
        controller: 'UserController',
        controllerAs: 'user'
    }).otherwise({
        redirectTo: '/user'
    });
});

userController.js

angular.module('userController', [])
.controller('UserController', function() {

});

But when I hit the url i.e. http://0.0.0.0:3000 in my browser, it redirects the url to http://0.0.0.0:3000/user which is correct but when I try to reload it tells me Cannot GET /user which I guess is a response from Node server. How can I configure my application so that browser uses http://0.0.0.0:3000 or http://0.0.0.0:3000/user.

Update: NodeJS server code.

// grab all we need
var path = require('path');
var express = require('express');
var app = express();

// setup public folder
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + 'public');

// set up the server
var server = app.listen(3000, 'localhost', function() {
    console.log('Server connected at ' + this.address().address + ':' + this.address().port);
});

// export exposed variable
module.exports = app;

Solution

  • You need to add a catch-all rule for routing in your server code.

    Update code by adding this rule before setting-up your server:

    app.all('/*', function (req, res, next) {
        // Just send the index.html for other files to support HTML5Mode. Assuming your index.html is at application root
        res.sendFile('index.html', { root: __dirname });
    });
    

    This will catch all the other requests (different from the root) and redirect them back to index.html in order to support the HTML5 mode.

    Essentially, your server code should look like this:

    // grab all we need
    var path = require('path');
    var express = require('express');
    var app = express();
    
    // setup public folder
    app.use(express.static(path.join(__dirname, 'public')));
    app.set('views', __dirname + 'public');
    
    /* CATCH-ALL RULE HERE */
    app.all('/*', function (req, res, next) {
        // Just send the index.html for other files to support HTML5Mode
        res.sendFile('index.html', { root: __dirname });
    });
    
    // set up the server
    var server = app.listen(3000, 'localhost', function() {
        console.log('Server connected at ' + this.address().address + ':' + this.address().port);
    });
    
    // export exposed variable
    module.exports = app;