Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expressjs router not working

I am new to MEAN stack, so i am going through tutorials and it pretty clear that not all people use same logic. But now i am stuck on these two examples

Example One

// server.js
var express = require('express'),
    app = express(),
    port = 1337;
// indicating view folder
app.set('views', './views');
// indicating view engine
app.set('view engine', 'ejs');
// adding routes
require('./routes/index.js')(app);
require('./routes/user.js')(app);
//
app.listen(port);
module.exports = app;


./routes/index.js
module.exports = function(app) {
    // show indix view
    app.get('/', function(req, res) {
            res.render('index', {
                title: 'Index page',
            });
    });
};

above we are using get method from app (which is instance of express)

./routes/user.js
module.exports = function(app) {
    // showing user page
    app.route('/users').get(function(req, res) {
            res.render('user', {
                title: 'User page'
            });
    });
};

above we are using route method of express and then bind get to it

so when the app is running, and i access localhost:1337 index page is called and when localhost:1337/user is called user page is called

Example two Now when we use express myapp command, this example has some different logic

we have main app.js

var express = require('express');

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('/', routes);
app.use('/users', users);

app.listen(1337);

module.exports = app;

As you can see first we require index and user route files required and then we use app.use command to set routes.

in ./routes/index.js file

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

we get method router of express and then bind get method to it

so my question is, when i commit app.use('/', routes); and call localhost:1337 i get error but we have already using router in ./routes/index.js to show index page. this should work according to first example.

EDIT error msg

Error: Not Found
    at app.use.res.render.message (/home/vagrant/meanstack/myapp/app.js:30:15)
    at Layer.handle [as handle_request] (/home/vagrant/meanstack/myapp/node_modules/express/lib/router/layer.js:82:5)
    at trim_prefix (/home/vagrant/meanstack/myapp/node_modules/express/lib/router/index.js:302:13)
    at /home/vagrant/meanstack/myapp/node_modules/express/lib/router/index.js:270:7
    at Function.proto.process_params (/home/vagrant/meanstack/myapp/node_modules/express/lib/router/index.js:321:12)
    at next (/home/vagrant/meanstack/myapp/node_modules/express/lib/router/index.js:261:10)
    at SendStream.error (/home/vagrant/meanstack/myapp/node_modules/express/node_modules/serve-static/index.js:107:7)
    at SendStream.emit (events.js:95:17)
    at SendStream.error (/home/vagrant/meanstack/myapp/node_modules/express/node_modules/send/index.js:244:17)
    at SendStream.onStatError (/home/vagrant/meanstack/myapp/node_modules/express/node_modules/send/index.js:340:48)

i had this code to handle error

app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
})

now when i comment this code and comment app.use('/', routes); and run the server.js

i get this when i run localhost:1337

Cannot GET / 

if you still cannot see the error, try express app in folder and create a new file server.js and add below code and run node server.js

var express = require('express');
var path = require('path');
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('/', routes);
app.use('/users', users);

app.listen(1337);

module.exports = app;
console.log(" call 192.168.33.33:1337");
like image 260
Iori Avatar asked Jan 28 '15 15:01

Iori


1 Answers

I ran express-generator, created a new file server.js with the code you provided. Upon hitting my localhost:1337 I got a 'CANNOT GET /' error. I then uncommented this line inside server.js

app.use('/', routes);

And it worked.

EDIT:

The reason why you need to call app.use('/', routes) for the route handling to work is because when you call

var app = express();

At this point, the 'app' variable contains a reference to your express object in memory. Meaning when you call

var router = express.Router(); 

Router at this point is standalone object. Router has no reference to the app you created, meaning when you register your GET route with route.get(), it does not affect your app instance of express. Hence when you hit localhost:1337, you get an error until you register the route.

In order to register your router with your app, you need to export and require your router, and register it with

routes = require('path/to/router')
app.use('/', routes)

The reason why your first example worked, is because in that case, you were registering the route handler directly with your app instance, using app.get()

like image 57
Yuri Zarubin Avatar answered Nov 08 '22 22:11

Yuri Zarubin