routing in Node / express - node.js

app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var newproject = require('./routes/newProject');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/newproject', newproject);
// 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 handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
newproject .js
var express = require('express');
var router = express.Router();
var sql = require ('mssql');
router.get('/newproject', function(req, res) {
res.render('newProject');
});
module.exports = router;
newProject.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello
</body>
</html>
and a similar index.ejs in views .
My home directory works ie localhost:3000/ works but when i type
localhost:3000/newproject it poses the following error :
Error: Failed to lookup view "error" in views directory "F:\project\pcgWebApp\views"
at EventEmitter.render (F:\project\pcgWebApp\node_modules\express\lib\application.js:580:17)
at ServerResponse.render (F:\project\pcgWebApp\node_modules\express\lib\response.js:971:7)
at F:\project\pcgWebApp\app.js:47:7
at Layer.handle_error (F:\project\pcgWebApp\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (F:\project\pcgWebApp\node_modules\express\lib\router\index.js:315:13)
at F:\project\pcgWebApp\node_modules\express\lib\router\index.js:284:7
at Function.process_params (F:\project\pcgWebApp\node_modules\express\lib\router\index.js:335:12)
at next (F:\project\pcgWebApp\node_modules\express\lib\router\index.js:275:10)
at F:\project\pcgWebApp\app.js:36:3
at Layer.handle [as handle_request] (F:\project\pcgWebApp\node_modules\express\lib\router\layer.js:95:5)
anyone know whats going on - ?Please help - have tried doing npm install .
It does work if i place
router.get('/newproject', function(req, res) {
res.render('newProject');
});
in app.js and change router to app.get..

In newProject.js change this:
//...
router.get('/newproject', function(req, res) {
res.render('newProject');
});
For this:
//...
router.get('/', function(req, res) {
res.render('newProject');
});
Since newProject.js seems to be used as an external router, as you've written your code your final endpoint would be:
localhost:3000/newproject/newproject
Instead, you want it to be:
localhost:3000/newproject/
That's why you should specify '/' as the endpoint inside of your route: because route paths in Express are associative

I believe that your first error is stemming from this section of code:
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
More specifically, the part that is trying to render the error view. I would ensure that you have a error.ejs file / view in your views folder.
I would also change your /newproject root inside your new project.js file to just / as the root comes from the file name.

Related

How do I correctly import Express route modules?

I generated a project with express-generator.
In my routes directory, i have 2 files : index.js and users.js, and about.js that handles the /about route.
Accessing /about results in Error 404 : Page Not found.
When adding the handler for /about in app.js, the error was gone.
./app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index')
var aboutRouter = require('./routes/about');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/about', aboutRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development\
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
./route/index.js:
var express = require('express');
var app = express();
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.json( {
message : "Home Page (Requeste for list)",
method : req.method,
Succes : "True"
});
// res.render('index', { title: 'Express' });
})
module.exports = router;
./routes/about.js:
var express = require('express');
var router = express.Router();
router.get('/about', function(req, res) {
res.send('im the about page!');
});
router.post('/about', function(req, res) {
res.send('im the about page!');
});
module.exports = router;
Rewrite your router/about.js like this
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the about page!');
});
router.post('/', function(req, res) {
res.send('im the about page!');
});
module.exports = router;
Since in your app.js, you already declare the prefix /about at line 24, so you do not have to do it again in router/about.js
What is happening is that in app.js you have set the root for about rout as "/about" and inside "about.js" you have specified router.get('/about') again, what will result in, for accessing the about route having to use /about/about (you may try before fix it). For you to get the result that you are expecting you should use router.get(´/´) inside about.js and in app.js keep as it is app.use('/about', aboutRouter);. You can have a look at https://expressjs.com/en/guide/routing.html for more information. Regards.

node.js express app can't find jade view, 404 message responded

for my app i use node.js as backend and Express as framework. I use Netbeans as IDE and i get the following output.
Not Found
404
Error: Not Found
at /home/ingeborg/netbeans/GML/app.js:33:13
at Layer.handle [as handle_request] (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:317:13)
at /home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:335:12)
at next (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:275:10)
at /home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:635:15
at next (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:260:14)
at Function.handle (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:174:3)
at router (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:47:12)
I have the following data setup:
- node-modules
- public
- fonts
- images
- javascripts
- stylesheets
stylesheets.less
stylesheet.css
- routes
index.js
news.js
users.js
- views
index.jade
error.jade
news.jade
layout.jade
Gruntfile.js
app.js
gulpfile.js
package.json
the app.js looks like this
var news = require('./routes/news');
var index = 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('/', index);
app.use('/index', index);
app.use('/news', news);
app.use('/users', users);
and this is my index.jade
h3
a(href="news") link
and this my news.jade
h3 test
.
The routing is realised over route files.
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
router.get('/index', function(req, res, next) {
res.render('index');
});
module.exports = router;
the news.js router file is
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('news', function(req, res, next) {
res.render('news');
});
module.exports = router;
The following circumstances are
the routing on the links "/" and "index" works as wanted.
the routing on "/news" or "news" (tested in the rounting, app.js and view file) not. I have no clue why the routing isn't working. I hope i haven't forgotten sth.
Thx,
Inge
Your code works for me.
/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var news = require('./routes/news');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use('/news', news);
// 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 handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
/routes/news.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('news');
});
module.exports = router;
The news route file is missing. There you have to render your jade.
var news = require('./routes/news');

New route in Express JS 404 error

Trying to add a new route to this Express app using the Express app generator. this is the app.js file:
var express = require('express');
var path = require('path');
var favicon = require('serve-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 parse = require('./routes/parse');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/parse', parse);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found - from app.js');
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;
The lines i added are:
var parse = require('./routes/parse');
app.use('/parse', parse);
Then in the /routes directory i added parse.js that contains:
var express = require('express');
var router = express.Router();
router.get('/parse', function(req, res, next) {
res.send('return from parse.js');
});
module.exports = router;
I can hit the / and the /users resource using a browser and i get the expected result. But when i try to hit /parse i get this 404:
Not Found - from app.js
404
Error: Not Found - from app.js
at /home/bitnami/parsecsvapi/app.js:32:13
at Layer.handle [as handle_request] (/home/bitnami/parsecsvapi/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:312:13)
at /home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:330:12)
at next (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:271:10)
at /home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:618:15
at next (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:256:14)
at Function.handle (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:176:3)
at router (/home/bitnami/parsecsvapi/node_modules/express/lib/router/index.js:46:12)
Try /parse/parse in the URL
If you would like to use /parse, please use / instead of /parse in /routes/parse.js
Please refer /routes/index.js & /routes/users.js.
TL;DR;
app.js
var parse = require('./routes/parse');
app.use('/parse', parse);
routes/parse.js
var express = require('express');
var router = express.Router();
// the URL pattern will be used in conjunction with how its is being used
// in this case it would be '/parse' (from app.js) + '/parse' (as used in the next line)
// resulting in '/parse/parse'
router.get('/parse', function(req, res, next) {
res.send('return from parse.js');
});
module.exports = router;

Error: Not Found at app.use.res.render.message in nodejs / expressjs

I have setup new express (nodejs) project and while I tried to run url it shows me an error of 404 not found error. Yet I have not modified any single line of code and directory structure. I have used express-generator command to create express project's structure.
Can anyone provide me suggestions for following issues?
- Why default code does not run?
- How should I setup my project directory to prevent write this long url.
- How could I integrate my chat application with yii1 project.
Following are my code details.
URL : http://localhost:3000/wchat/wnode/users
Directory structure :
wchat/wnode/users
wchat : php project
wnode : node directory to implements instant notification and chat
users : module
Code files :
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-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');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
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;
index.js
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;
users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
Error :
Not Found
404
Error: Not Found
at app.use.res.render.message (/var/www/html/wchat/wnode/app.js:30:13)
at Layer.handle [as handle_request] (/var/www/html/wchat/wnode/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:312:13)
at /var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:330:12)
at next (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:271:10)
at /var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:618:15
at next (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:256:14)
at Function.handle (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:176:3)
at router (/var/www/html/wchat/wnode/node_modules/express/lib/router/index.js:46:12)
Looking at your routes,
app.use('/', routes); -> handlers GET on localhost:3000
app.use('/users', users); -> handles GET on localhost:3000/users
So there is nothing to handle localhost:3000/wchat/wnode/users. Hence the 404.
If you want to handle something like localhost:3000/wchat/wnode/users,
you need to have a route like
router.verb('/wchat/wnode/users', function (req, res, next) {
// handle whatever you want.
});
Looking at your code and what url you are trying to GET, i would really suggest to familiarize yourself with how express handles routing. More info here

I am working on Express 4 Application on Node.js. I have having problems rendering a new view

I used the Express generator to generate an express 4 application. Once I did that I replaced the jade templating engine with ejs. I am now trying to add a new route at /players. When I try and navigate to myapp/players I am receiving this error :
Error: Failed to lookup view "error" in views directory "/home/fk/d/e/goose/views"
at EventEmitter.app.render (/home/fk/d/e/goose/node_modules/express/lib/application.js:555:17)
at ServerResponse.res.render (/home/fk/d/e/goose/node_modules/express/lib/response.js:938:7)
at module.exports (/home/fk/d/e/goose/app.js:65:7)
at Layer.handle_error (/home/fk/d/e/goose/node_modules/express/lib/router/layer.js:58:5)
at trim_prefix (/home/fk/d/e/goose/node_modules/express/lib/router/index.js:300:13)
at /home/fk/d/e/goose/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/home/fk/d/e/goose/node_modules/express/lib/router/index.js:321:12)
at IncomingMessage.next (/home/fk/d/e/goose/node_modules/express/lib/router/index.js:261:10)
at fn (/home/fk/d/e/goose/node_modules/express/lib/response.js:933:25)
at EventEmitter.app.render (/home/fk/d/e/goose/node_modules/express/lib/application.js:557:14)
My file structure is
|Myapp"goose"
-bin
-config
-node modules
-public
-routes
--index.js
--users.js
--players.js
-views
--index.ejs
--users.ejs
--players.ejs
--error.ejs
-app.js
-package.json
Here is the code contained in my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var routes = require('./routes/index');
var users = require('./routes/users');
var players = require('./routes/players');
var app = express();
var configDB = require('./config/database.js');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/players', players);
// 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;
Here is the code for my routes/players.js
var express = require('express');
var router = express.Router();
/* GET players page. */
router.get('/players', function(req, res, next) {
res.render('players', { title: 'Players' });
});
module.exports = router;
My index view is currently still working fine. Thank you for your help in advance and please let me know if there is any more information I can provide that would be of assistance.
**EDIT 1: ** I have added an error.ejs file which is reflected above in the file structure. I believe what was causing all the error messages above was my application was trying to render the error.ejs when I was navigating to /players. Now when I am trying to navigate to /players I am being redirected to the new error.ejs view.
Edit 2: This problem has been solved. Please look at user Jonathan Lonowski's answer below for a detailed explanation. Thank you Johnathon.
The initial issue is that requesting GET /players will result in a 404 Not Found.
This is because the route is defined as GET /players/players since Express combines the .use() and router paths:
app.use('/foo', fooRouter);
// GET /foo/bar
fooRouter.get('/bar', ...);
When specifying a "prefix" with .use(), you can define routes for the "root" of that prefix in the router:
// GET /players = /players + /
router.get('/', ...);

Resources