Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressJS paired with AngularJS Routing without hashtag on links

I'm trying to implement a routing function on my ExpressJS Server.

http://localhost:3000/app/sub_one
http://localhost:3000/app/sub_two

Unfortunately, I am able to make this work with a prefix of # in between the application name and the module. I've been searching for the solution and it seems this code would do it in my angular config - $locationProvider.html5Mode(true);.

But having that implemented and adjusting the link, access the following link returns an unusual behaviour.

http://localhost:3000/app/sub_one => Cannot GET /app/sub_one
http://localhost:3000/app/sub_two => Cannot GET /app/sub_two

I may have the intuition that the problem is my routing on the server.js.

var port = 3000;
var express = require("express");
var morgan = require("morgan");
var server = express();

server.use(morgan("tiny"));
server.use("/app", express.static(__dirname + "/app"));
server.use("/bower_components", express.static(__dirname + "/bower_components"));
server.listen(port, function() {
    console.log("Node server initialized. Server's port: " + port);
});

I have placed a repository for this problem on Bitbucket

like image 201
David B Avatar asked Dec 10 '14 08:12

David B


1 Answers

I may be wrong about this, but it seems that you may be confusing client side routes with server side routes.

Routes defined via ngRouter are not supposed to hit server at all.

I modified your code to make it work. It should be enough to let you go on your own -- if you have any questions, give me a shout.

Forked repo with below changes.

Files after the changes:

config.js

var angular = angular.module("NodeAngularJSRouting", ["ngRoute"]);

angular.config(function($routeProvider, $locationProvider) {
    $routeProvider
        .when("/app/sub_one", {
            templateUrl: "/view/sub_view_one/list.html",
            controller: "SubViewOneCtrl" })
        .when("/app/sub_two", {
            templateUrl: "/view/sub_view_two/list.html" })
        .otherwise({
            templateUrl: "/view/default/default.html",
            controller: "DefaultCtrl" });

    $locationProvider.html5Mode(true);
});

server.js

var port = 3000;
var express = require("express");
var morgan = require("morgan");
var server = express();

server.use(morgan("tiny"));

// serve bower components statically
server.use("/bower_components", express.static(__dirname + "/bower_components"));

// for all routes defined on client side send
// entry point to the app
// btw. changes of those routes on client side
// are not supposed to hit server at all (!)
server.use("/app*", function(req, res, next){
    res.sendFile(__dirname + '/app/main.html');
});

// for all public requests try to use /app folder
server.use("/", express.static(__dirname + "/app"));

server.listen(port, function() {
    console.log("Node server initialized. Server's port: " + port);
});

index.html

renamed to main.html

<!DOCTYPE html>
<html ng-app="NodeAngularJSRouting" >
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1">
        <title>Node AngularJS Routing</title>

        <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css">
        <link rel="stylesheet" href="/view/css/styles.css">
    </head>
    <body>
        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
            <div class="container-fluid">
                <!-- Brand and toggle get grouped for better mobile display -->
                <div class="navbar-header">
                    <a class="navbar-brand" href="/app">Node AngularJS Route</a>
                </div>

                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="/app/sub_one">View One</a></li>
                        <li><a href="/app/sub_two">View Two</a></li>
                    </ul>
                </div><!-- /.navbar-collapse -->
            </div><!-- /.container-fluid -->
        </nav>

        <div class="container" ng-view></div>

        <script src="/bower_components/jquery/dist/jquery.js"></script>
        <script src="/bower_components/bootstrap/dist/js/bootstrap.js"></script>
        <script src="/bower_components/angular/angular.js"></script>
        <script src="/bower_components/angular-route/angular-route.js"></script>
        <script src="/config/config.js"></script>
        <script src="/controller/default-default.js"></script>
        <script src="/controller/sub-one_list.js"></script>
    </body>
</html>
like image 186
artur grzesiak Avatar answered Oct 03 '22 17:10

artur grzesiak