bonum_cete
bonum_cete

Reputation: 4962

node.js/angular.js - Cannot GET

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);
}]);

Upvotes: 15

Views: 26586

Answers (4)

Despertaweb
Despertaweb

Reputation: 1820

I'd suggest a pretty fast javascript solution in front and back end.

NodeJs

// set up our one route to the index.html file
    app.get('*', function (req, res){
    res.sendFile(path.join(__dirname+'/public/index.html'));
});

This code tells to de local/remote server where is the main html, so it could find the rest of templates.

AngularJs

// If 404 Redirect to home
$routeProvider.otherwise( { redirectTo: '/'} );

This is also really helpful, so never goes to a missing page.

Upvotes: 2

GordyD
GordyD

Reputation: 5103

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

Upvotes: 12

Benjamin Crouzier
Benjamin Crouzier

Reputation: 41855

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); }));
    }
  }
}

Upvotes: 8

Maxim Grach
Maxim Grach

Reputation: 4288

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);

Upvotes: 4

Related Questions