Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am in the beginning stages of a node.js/angular.js project. I am seeing some strange behavior.

I have the root route and it works fine. I also have a another route 127.0.0.1:3000/dashboard if I just type that url into the address bar I get this error:

Cannot GET /dashboard

If I create a link to the same url it works fine.

If I then refresh that page I get the same error again.

Below is my node.js route

app.js

/**
* Module dependencies.
 */

var express = require('express')
  , routes  = require('./routes')
  , stats   = require('./routes/stats')
  , tests   = require('./routes/test')
  , http    = require('http')
  , util    = require('util')
  , path    = require('path');

var app = module.exports = express();

app.configure(function(){

  /*
   * Configuration
   *
   */
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');

  /*
   * Middleware definitions
   *
   */
  app.use(express.favicon());
  app.use(express.logger('dev'));
  /*
   * Error handling middleware
   */
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('shhhhhhhh, super secret'));
  app.use(app.router);

  // serves up dynamic css files
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(require('less-middleware')({ src: __dirname + '/public' }));

  // serves a static path
  app.use(express.static(path.join(__dirname, 'public')));

});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    app.use(express.errorHandler());
});


/*
 * Endpoints
 */
app.get('/', routes.index);

app.get('/test', tests.get);
app.post('/test', tests.post);
app.options('/test', tests.options);

app.get('/stats/sends', stats.sends.get);
app.get('/stats/events', stats.events.get);
app.get('/stats/attempts', stats.attempts.get);
app.get('/stats/errors', stats.errors.get);
app.get('/stats/mquad', stats.mquad.get);

app.get('/partials/:name', routes.partials);
app.get('/index/landing', routes.landing);
app.get('/index/dashboard', routes.dashboard);

console.log('Env: ' + app.settings.env);
http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

routes/index.js

    exports.dashboard = function(req, res){
        res.render('dashboard');
    };

Angular route

    'use strict';
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).
    config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider.
        when('/', {
            templateUrl: 'partials/landing',
            controller: LandingCtrl
        }).
        when('/dashboard', {
            templateUrl: 'partials/dashboard',
            controller: DashboardCtrl
        }).
        otherwise({
            redirectTo: '/'
        });
    $locationProvider.html5Mode(true);
}]);

Thanks for any help!

share|improve this question

3 Answers 3

The reason this does not work is that your server is not catching all other routes and routing them to your single page app which is served by routes.index.

In order to catch all other routes and route them to the index page so that your angular app can see if it matches the supplied url all you need to do is add the following line after your last route is declared:

app.get('*', routes.index);

Now you should be able to:

  • navigate directly to a url served by your Angular.js app
  • refresh any page without error
share|improve this answer

This article might help:

http://jjt.io/2013/11/16/angular-html5mode-using-yeoman-generator-angular/

In a nutshell:

npm install --save-dev connect-modrewrite

Gruntfile:

connect: {
  options: {
    // ...
    // Modrewrite rule, connect.static(path) for each path in target's base
    middleware: function (connect, options) {
      var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
      return [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat(
        optBase.map(function(path){ return connect.static(path); }));
    }
  }
}
share|improve this answer

Route app.get('/index/dashboard', routes.dashboard); refers to http://hostname/index/dashboard whereas when('/dashboard', { ... }) refers to http://hostname/dashboard.

You should correct the route: app.get('/dashboard', routes.dashboard);

share|improve this answer
    
Thanks for the reply. However, I get this 500 Express 500 Error: Failed to lookup view "dashboard" when I use the route app.get('/dashboard', routes.dashboard); –  isea Feb 5 '13 at 4:58
    
@isea could you show full code of your server.js and app.js? –  Maxim Grach Feb 5 '13 at 5:00
    
I updated my question –  isea Feb 5 '13 at 5:08
    
Try when('/index/dashboard', { ... }). You are using html5Mode and all your app routes should be equal to the server routes. –  Maxim Grach Feb 5 '13 at 5:23
    
nope, that also produces a 500 –  isea Feb 5 '13 at 5:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.