Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Ui-Router isn't routing while using node.js

I am using angular ui router. The router seems to work perfect on the home page index.html. But any other navigation doesn't work.

Here is my stateprovider angular:

var app = angular.module('myApp', ['ui.router']);


app.config(function($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/");

    $stateProvider
        .state("home", {
            url: "/",
            templateUrl: "../partials/home/index.html"
        })
        .state("login", {
            url:"/login",
            templateUrl: "../partials/account/login.html"
        })
        .state("register", {
            url: "/register",
            templateUrl: "../partials/account/register.html"
        })
        .state("values", {
            url: "/values",
            templateUrl: "../partials/test/values.html"
        })
    ;
});

HTML in my main index.html:

 <!--Content -->
    <div class="container">
        <div ui-view></div>
    </div>
    <!-- END Content -->

When I navigate the the page localhost:8080/login I get this:

enter image description here I would think I shouldn't even be seeing this page if it can't find it. Shouldn't it redirect me back to "/" because of $urlRouterProvider.otherwise(). Besides that point though the template url /partials/account/login.html Does Exist.

I am somewhat new to node.js and I am curious if the note file server is trying to route and trumping my angular one? I am using http-server which is probably the most common one.

I am also using Express Node if that helps. And here is the code for app.js where I think the problem may be coming from:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


module.exports = app;
like image 611
allencoded Avatar asked Jun 06 '14 00:06

allencoded


2 Answers

I figured it out. Doing the below made it work.

app.use(function(req, res) {
    // Use res.sendfile, as it streams instead of reading the file into memory.
    res.sendfile(__dirname + '/public/index.html');
});

The entire app.js incase anyone is curious where it goes.

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));


app.use(function(req, res) {
    // Use res.sendfile, as it streams instead of reading the file into memory.
    res.sendfile(__dirname + '/public/index.html');
});

app.use('/', routes);



/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


module.exports = app;

Of course this will need to be in your angular code:

app.config(["$locationProvider", function($locationProvider) {
    $locationProvider.html5Mode(true);
}]);

One thing to note that got me. You must restart the server for this to work. ctr+c then paste this code then restart server. Good luck

like image 161
allencoded Avatar answered Oct 23 '22 07:10

allencoded




have you tried using the same directory for your partials :
moving partials/account/login.html" to partials/home/login.html"
Also, are you using your own server.js express configuration, or a yeoman fullstack ?
angular is clearly handling the routing, but it seems that nodejs is not finding the assets...

Be sure to have a specific task for serving partial files in your server.js

    function serve_partial(req,res){
      var stripped = req.url.split('.')[0];
      var requestedView = path.join('./', stripped);
      res.render(requestedView, function(err, html) {
        if(err) {
          res.render('404');
        } else {
          res.send(html);
        }
      });
    }

    function serve_index(req,res){
      res.render('index');
    }

    // Angular Routes
    app.get('/partials/*', serve_partial);
    app.get('/*', serve_index);

for your case, it might me something as :

    var express = require('express');
    var path = require('path');
    var favicon = require('static-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');

    var routes = require('./routes/index');
    var users = require('./routes/users');

    var app = express();

    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');

    app.use(favicon());
    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded());
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));

    function serve_partial(req,res){
      var stripped = req.url.split('.')[0];
      var requestedView = path.join('./', stripped);
      res.render(requestedView, function(err, html) {
        if(err) {
          res.render('404');
        } else {
          res.send(html);
        }
      });
    }

    app.use('/partials/*', serve_partial);
    app.use('/', routes);
    app.use('/users', users);

    /// catch 404 and forward to error handler
    app.use(function(req, res, next) {
        var err = new Error('Not Found');
        err.status = 404;
        next(err);
    });

    /// error handlers

    // development error handler
    // will print stacktrace
    if (app.get('env') === 'development') {
        app.use(function(err, req, res, next) {
            res.status(err.status || 500);
            res.render('error', {
                message: err.message,
                error: err
            });
        });
    }

    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: {}
        });
    });


    module.exports = app;
like image 25
Mahmal Sami Avatar answered Oct 23 '22 08:10

Mahmal Sami