Unable to set separate route files in Express JS - javascript

I want to separate my login route from default app.js and route/index.js files but I'm not getting error 404 Not Found while executing localhost:3000/login
I know this questions has been asked already before and I've followed other answers on StackOverflow but not getting why I'm getting error.
Stack overflow question I followed:
How to separate routes on Node.js and Express 4?
I'm not getting why I'm getting this error.
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 expressValidator = require('express-validator');
var session = require('express-session');
var mongodb = require('./mongoDB');
var index = require('./routes/index');
var users = require('./routes/users');
var login = require('./routes/login'); //including login.js
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(session({
name: 'mysession',
secret: 'some_secret',
saveUninitialized: false,
resave: true, cookie: {
secure: true
}}));
app.use('/', index);
app.use('/users', users);
app.use('/login', login);
mongodb.connectDatabase;
// 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;
route/login.js
var express = require('express');
var router = express.Router();
router.get('/login', function (req, res) {
res.send('exec');
});
module.exports = router;
localhost:3000/login
Not Found
404
Error: Not Found
at /home/jatin/Drive/OpenSource/sessionManager/app.js:44:13
at Layer.handle [as handle_request] (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:312:13)
at /home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:330:12)
at next (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:271:10)
at /home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:618:15
at next (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:256:14)
at Function.handle (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:176:3)
at router (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:46:12)
at Layer.handle [as handle_request] (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:312:13)
at /home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:330:12)
at next (/home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:271:10)
at /home/jatin/Drive/OpenSource/sessionManager/node_modules/express/lib/router/index.js:618:15

It's a little confusing, but when you use:
app.use('/login', login);
You are nesting all routes defined in login under the /login namespace. You can probably currently access the route at /login/login
Change your login.js to:
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.send('exec');
});
module.exports = router;
Then /login/ will correctly be routed to the / route of the login namespace

Related

File Upload returning "undefined"

So I am using Express File Upload and when I attempt to send a post request to it, it returns the error from the error-handler that is set up, which essentially it couldn't find any files when I console.log(req.files) it returns undefined, which is why the error is being sent back, but I don't know how to fix the problem.
Index.js
router.post('/upload-avatar', async (req, res) => {
try {
console.log(req.files)
if(!req.files) {
res.send({
status: false,
message: 'No file uploaded'
});
} else {
//Use the name of the input field (i.e. "avatar") to retrieve the uploaded file
let avatar = req.files.avatar;
//Use the mv() method to place the file in upload directory (i.e. "uploads")
avatar.mv('./uploads/' + avatar.name);
//send response
res.send({
status: true,
message: 'File is uploaded',
data: {
name: avatar.name,
mimetype: avatar.mimetype,
size: avatar.size
}
});
}
} catch (err) {
res.status(500).send(err);
}
});
App.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const fileUpload = require('express-fileupload');
const cors = require('cors');
const bodyParser = require('body-parser');
const _ = require('lodash');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
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('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
app.use(fileUpload({
createParentPath: true
}));
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// 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;
I am using an azure server, and at the moment I am using postman to get it working first!
Thanks In Advance!
Middlewares should be ordered appropriately. Your file upload middleware was placed below your index router. So when a request hits the server Express would run your indexRouter’s handler before the upload middleware and unless your handler calls next(), the file upload middleware would not process your request. And you cannot call next() since it would mean “I’m done with my part, hand this request (req) to the next middleware/handler”.
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const fileUpload = require('express-fileupload');
const cors = require('cors');
const bodyParser = require('body-parser');
const _ = require('lodash');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
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(fileUpload({
createParentPath: true
}));
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use('/', indexRouter);
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;

req.body throws an empty {}

I am using body-parser but it's not working and I don't know what the problem is.
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const bodyParser = require('body-parser');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
//bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
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('/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;
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', redirection, function(req, res, next) {
res.redirect('index', {title: 'Home'});
});
router.get('/country', function(req, res, next) {
// CountryName
res.render('country',
{
title: 'Home',
mainJS: 'main.js',
//country: req.body.countries
});
console.log(req.body)
});
function redirection(req, res){
if (req.url == '/'){
res.redirect('/country');
}
}
module.exports = router;
In this code it throws {}
What is the problem?
Your server only receives a request body in POST (or PUT or PATCH) operations, not in GET operations. You don't have router.post() in your sample code, so it seems you are not handling POSTs. Therefore, no req.body.
You can find your https://example.com/?query=parameters&query2=parameters at req.params.query and req.params.query2.
You can't use the location bar of a browser to do a POST: they from a form posts or xhr / fetch operations.

Express renders index.html but no other page

I have an express app to just serve static html files.
let express = require('express');
let path = require('path');
let cookieParser = require('cookie-parser');
let logger = require('morgan');
let indexRouter = require('./routes/index');
let usersRouter = require('./routes/users');
let appRouter = require('./routes/app');
let app = express();
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('/users', usersRouter);
app.use('/app', appRouter);
module.exports = app;
In /public I have index.html and app.html
In /routes/ I have index.js and app.js
Both of them are basically identical
index.js
let express = require('express');
let router = express.Router();
router.get('/', function (req, res, next) {
res.render('index');
});
module.exports = router;
app.js
let express = require('express');
let router = express.Router();
router.get('/', function (req, res, next) {
res.render('app');
});
module.exports = router;
When I access localhost:3000 the index.html file is displayed perfectly.
When I access localhost:3000/app I get the error
Error: No default engine was specified and no extension was provided.
at new View (C:\a\Web\todo\node_modules\express\lib\view.js:61:11)
at Function.render (C:\a\Web\todo\node_modules\express\lib\application.js:570:12)
at ServerResponse.render (C:\a\Web\todo\node_modules\express\lib\response.js:1008:7)
at C:\Voliware\Web\todo\routes\app.js:5:9
at Layer.handle [as handle_request] (C:\a\Web\todo\node_modules\express\lib\router\layer.js:95:5)
at next (C:\a\Web\todo\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\a\Web\todo\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\a\Web\todo\node_modules\express\lib\router\layer.js:95:5)
at C:\a\Web\todo\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\a\Web\todo\node_modules\express\lib\router\index.js:335:12)
You said 'just serve static html files.'. then mark the following 3 lines.
// app.use('/', indexRouter);
// app.use('/users', usersRouter);
// app.use('/app', appRouter);
and access access localhost:3000/app.html not access localhost:3000/app. because you don't have a static file named 'app'.
Try adding this to your middle ware stack
app.set('view engine', 'html');

Express and Mongoose: Cannot read property 'name' of undefined in Postman

I am attempting to create and insert 'user' json documents, defined in the model below, upon a POST request to localhost:3000/api/student. I am greeted with the following error using postman to send POST requests:
TypeError: Cannot read property 'name' of undefined
at module.exports.makeStudent (/home/tyler/Dropbox/Projects/Curricula/API/controllers/student.js:17:22)
at Layer.handle [as handle_request] (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/layer.js:95:5)
at next (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/layer.js:95:5)
at /home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/index.js:330:12)
at next (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/index.js:271:10)
at Function.handle (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/index.js:176:3)
at router (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/router/index.js:46:12)
Below are what I believe to be the relevant files
API/models/student.js
var mongoose = require('mongoose')
var studentSchema = new mongoose.Schema({
name: {type: String, required: true},
password: {type: String, required: true},
classes: [Number]
});
mongoose.model('Student', studentSchema);
API/controllers/student.js
var mongoose = require('mongoose');
var Student = mongoose.model('Student');
var sendJSONResponse = function(res, status, content){
res.status(status);
res.json({content});
}
module.exports.listStudents = function (req, res) {
sendJSONResponse(res, 200, {"status" : "success"});
};
module.exports.studentIDLookup = function (req, res) { };
module.exports.studentAuth = function (req, res) { };
module.exports.studentNametoID = function (req, res) { };
module.exports.makeStudent = function (req, res) {
Student.create({
name : req.body.name,
password : req.body.password,
email : req.body.email
}, function(err, student){
if(err){
sendJSONResponse(res, 400, err)
}
else{//success
sendJSONResponse(res, 201, student);
}
})
};
module.exports.deleteStudent = function (req, res) { };
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');
require('./API/models/db')
var app = express();
// view engine setup
app.set('views', path.join(__dirname,'app','views'));
app.set('view engine', 'jade');
//routes
var indexRoute = require('./app/routes/index');
app.use('/', indexRoute);
var apiRoute = require('./API/routes/index.js')
app.use('/api', apiRoute);
// 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')));
// 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');
});
// Export app to module
module.exports = app;
Any insight to what I am doing wrong would be appreciated.
The order in which you declare routes/middleware is incorrect:
//routes
var indexRoute = require('./app/routes/index');
app.use('/', indexRoute);
var apiRoute = require('./API/routes/index.js')
app.use('/api', apiRoute);
// 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 }));
This means that the body-parser middleware, which is used to populate req.body, won't get called for requests made to / and requests starting with /api, because those routes are declared before the body-parser middleware is declared.
The solution is to move body-parser (and logger as well, probably) to before the route declarations:
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//routes
var indexRoute = require('./app/routes/index');
app.use('/', indexRoute);
var apiRoute = require('./API/routes/index.js')
app.use('/api', apiRoute);
first of all, you should install body-parser using npm:
npm i --save body-parser
then, add it to your js file like below:
const bodyParser = require('body-parser');
for adding parser like urlencoded for post requests, use the below line:
const urlencodedParser = bodyParser.urlencoded({ extended: false });
finally, add urlencodedParser to your request as a middleware:
app.post('/', urlencodedParser, (req,res) => {})

node js app variable is not defined in coffeescript

I am just going through nodejs, expressjs and coffeescript. My code is,
app.js
require('coffee-script').register();
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 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);
require('./apps/authentication/routes')(app);
// 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;
My CoffeeScript Code is.
routes.coffee
routes = (app) ->
app.get "/login", (req , res) ->
res.render "views/login",
title: 'Login'
stylesheet: 'login'
module.export = routes
When i run project, i face following issue.
app.get("/login", function(req, res) {
^
ReferenceError: app is not defined
can anyone tell me why app variable is not defined at whereas i am passing app variable when requiring route?
If i remove white spaces from coffeescript file as mentioned below
routes = (app) ->
app.get "/login", (req , res) ->
res.render "views/login",
title: 'Login'
stylesheet: 'login'
module.export = routes
it return exception require(...) is not a function as mentioned below
require('./apps/authentication/routes')(app);
^
TypeError: require(...) is not a function
Thanks
Finally, I am able to fix this, it was syntax error in coffeescript.
I just changed
module.export
to
module.exports
Thanks,

Categories