I am new to expressjs. I am sending data from a web form to another form(or show on console) with the POST request. But I am receiving a empty object. My routes are in separate folder where i handling the data. I used body-parser as middleware for handling the request body.
This is a simple webform
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<title>Login</title>
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Login</h1>
</div>
<form method="POST" class="col-md-8" action="/profile">
<div class="form-group row">
<div class="col-md-4">
<label for="email" class="form-control border-0">Email</label>
</div>
<div class="col-md-8">
<input type="email" class="form-control" id="email" placeholder="Enter email">
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<label for="password" class="form-control border-0">Password</label>
</div>
<div class="col-md-8">
<input type="password" class="form-control" id="password" placeholder="Enter Password">
</div>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</body>
</html>
This is the route file(route.js)
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json(); // support json encoded bodies
var urlencodedParser = bodyParser.urlencoded({ extended: false }); // support encoded bodies
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
router.get('/login', (req, res)=>{
res.render('auth/login');
});
router.post('/profile', urlencodedParser, function(req, res){
res.send("THank you");
console.log("called post");
console.log(req.body);
});
module.exports = router;
This 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');
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json(); // support json encoded bodies
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));
});
// 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;
You need to put name attribute to HTML <input> tag, for ex:
<input name="email" type="email" class="form-control" id="email" placeholder="Enter email">
Related
editUser.js which is loading the data correctly, however when clicking on update I am getting (404 not found error), not able to understand why update route is not getting invoked. It is working for /, createUser, editUser/:id (for loading user data).
editUser.js
<div class="container">
All Users
<form class="col g-3 mt-3"" method="post" action="/update/<%= user.id %>">
<div class="col-md-6">
<label for="inputFirstName" class="form-label">First Name:</label>
<input type="text" class="form-control" value="<%= user.first_name %>" name="first_name" id="first_name">
</div>
<div class="col-md-6">
<label for="inputLastName" class="form-label">Last Name</label>
<input type="text" class="form-control" value=<%= user.last_name%> name="last_name" id="last_name">
</div>
<div class="col-md-6">
<label for="inputEmail" class="form-label">Email</label>
<input type="email" class="form-control" value=<%= user.email%> name="email" id="email">
</div>
<div class="col-md-6 mt-3">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
routes/index.js
var express = require('express');
var router = express.Router();
var {allUsers, createUser, saveUser, editUser, updateUser} = require('../controllers/userController')
/* GET users listing. */
//Commenting default function
router.get('/', allUsers)
router.get('/createUser', createUser)
router.post('/createUser', saveUser)
router.get('/editUser/:id', editUser)
router.post('/updateUser/:id', updateUser)
module.exports = router;
controllers/userController.js
const User = require('../models/userModel')
const updateUser = async (req, res) => {
console.log('Updating User')
const userId = req.params.id
const userData = req.body
const selector = {where: {id:userId}}
await User.update(userData, selector).catch(error => console.log(error))
res.redirect('/')
}
module.exports = { allUsers,createUser,saveUser,editUser,updateUser }
app.js
//Imports
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressLayouts = require('express-ejs-layouts')
const routes = require('./routes');
//DOTENV for storing sensitive data
require('dotenv').config({path:'./bin/.env'})
var app = express();
// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); //Key, Value
app.set('layout','layouts/layout')
//Middleware between requet and response
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(expressLayouts)
//Use Router
app.use('/',routes)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
//error handler first parameter is "err"
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;
Form action should be action="/updateUser/<%= user.id %>
Trying out Node.js for the first time. My POST route is failing with "Cannot POST /admin/add-product.html". GET request is being served fine from the same route. I have had a look around here. Several answers to similar issues but nothing is helping. Here is my code:
./index.js
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const adminRoutes = require('./src/routes/admin');
const shopRoutes = require('./src/routes/shop');
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.listen(3000);`
./src/routes/admin.js
const path = require('path');
const express = require('express');
const router = express.Router();
// served on /admin/add-product GET route
router.get('/add-product', (req, res, next) => {
res.sendFile(path.join(__dirname, '../', 'views', 'add-product.html'));
});
// served on /admin/add-product POST route
router.post('/add-product', (req, res, next) => {
console.log(req.body);
res.redirect('/');
// res.send('<h1>product saved</h1>');
});
module.exports = router;
./src/views/add-product.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add Product</title>
</head>
<body>
<header>
<nav>
<ul>
<li>Shop</li>
<li>Add Product</li>
</ul>
</nav>
</header>
<main>
<form action="/admin/add-product.html" method="POST">
<input type="text" name="title" /><button type="submit">
Add Product
</button>
</form>
</main>
</body>
</html>
Thank you!!!
The action in the form need to match the route declare in the NodeJS application, it should be :
<form action="/admin/add-product" method="POST">
Remove the .HTML from the action attribute of the form.
IF i am not logged in and make "GET" request to "/sell" i am redirected to "/user/login" which is working accordingly.But if i am logged in and i make GET request to "/sell" i am always redirected to
"/" i.e. homepage instead of "/sell" page.so what should i do to only access "/sell" page if i am logged in?.Here are the code snippets you may probably need. Please let me know if u need anything else. Thank you in advance.
/routes/sell.js
const express = require('express');
const router = express.Router();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({extended:false});
const Product = require('../models/product');
router.get('/sell', isLoggedIn, (req, res, next) => {
res.render('sell',{title: 'Home|Sell', success: req.session.success, errors: req.session.errors, csrfToken: req.csrfToken()});
req.session.success = null;
req.session.errors = null;
})
router.post('/book_upload', isLoggedIn, (req, res, next) => {
req.check('name')
.isLength({min:3}).withMessage('Name must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Name must be alphabetic.');
req.check('phone')
.isLength({min:10,max:10}).withMessage('Phone number must be of 10 digits.');
req.check('book_name')
.isLength({min:3}).withMessage('Book Name must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Book Name must be alphabetic.');
req.check('book_price')
.isNumeric().withMessage('Price must be numeric.');
req.check('description')
.isLength({min:3}).withMessage('Description must be of 3 characters long.')
.matches(/^[<A-Za-z0-9></A-Za-z0-9>\s]+$/).withMessage('Please write appropriate description.')
req.check('faculty')
.isLength({min:3}).withMessage('Faculty must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Faculty must be alphabetic.')
var errors = req.validationErrors();
if (errors){
req.session.errors = errors;
req.session.success = false;
} else {
req.session.success = true;
var item = {
name: req.body.name,
phone: req.body.phone,
book_name: req.body.phone,
book_price: req.body.price,
description: req.body.description,
faculty: req.body.faculty
};
var data = new Product(item);
data.save();
}
res.redirect('/sell');
})
function isLoggedIn (req, res, next){
if (req.isAuthenticated()){
return next();
}
req.flash('error', 'Please Login to Continue')
res.redirect('/user/login');
}
module.exports = router;
and 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 expressHbs = require('express-handlebars');
var mongoose = require('mongoose');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var validator = require('express-validator');
// var MongoStore = require('connect-mongo')(session);
mongoose.connect('mongodb+srv://username:password#firstdatabase-ytrfr.mongodb.net/test?retryWrites=true&w=majority',{
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(()=>console.log('Connected to the database'))
.catch(err=> console.log('could not connect.',err.message))
// passport
require('./config/passport');
var indexRouter = require('./routes/index');
var userRouter = require('./routes/user');
var sellRouter = require('./routes/sell');
var app = express();
// view engine setup
app.engine('.hbs', expressHbs({ defaultLayout: 'layout', extname: '.hbs'}))
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(validator());
app.use(session({
secret: 'blahblah',
resave: false,
saveUninitialized: false,
}))
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use((req, res, next) => {
res.locals.login = req.isAuthenticated();
res.locals.session = req.session;
next();
})
app.use('/', indexRouter);
app.use('/', userRouter);
app.use('/', sellRouter);
// 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;
and sell.hbs
<section class="my_account_area pt--80 pb--55 bg--white">
<div class="container">
<div class="row">
<div class="col-lg-6 col-12">
<div class="my__account__wrapper">
{{# if success}}
<section class="success">
<h2>Form submitted!</h2>
</section>
{{else}}
{{# if errors}}
<div class="alert alert-danger">
<section class="errors">
<ul>
{{# each errors}}
<li>{{ this.msg }}</li>
{{/each}}
</ul>
</section>
</div>
{{/if}}
<h3 class="account__title">Fill Up the Information of Book</h3>
<form action="/book_upload" method="post">
<div class="account__form">
<div class="input__box">
<label>Your Name <span>*</span></label>
<input type="text" id="name" name="name">
</div>
<div class="input__box">
<label>Phone No. <span>*</span></label>
<input type="number" id="phone" name="phone">
</div>
<div class="input__box">
<label>Name of book <span>*</span></label>
<input type="text" id="book_name" name="book_name">
</div>
<div class="input__box">
<label>Price of Book<span>*</span></label>
<input type="number" id="book_price" name="book_price">
</div>
<div class="input__box">
<label>Description of Book<span>*</span></label>
<input type="text" id="description" name="description" placeholder="e.g. To study in 1st year 1st part">
</div>
<div class="input__box">
<label>Faculty<span>*</span></label>
<input type="text" id="faculty" name="faculty">
</div>
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
<div class="form__btn">
<button type="submit">Upload</button>
</div>
</div>
</form>
</div>
{{/if}}
</div>
</div>
</div>
</section>
Middleware functions are executed sequentially, therefore the order of middleware inclusion is important.
Hence, change the order of
app.use('/', indexRouter);
app.use('/', userRouter);
app.use('/', sellRouter);
to
app.use('/', sellRouter);
app.use('/', indexRouter);
app.use('/', userRouter);
It will work.
I have an express app that takes basic user input data. All of my get routes work fine but when submit a post request to the server I get a 404 on the url I'm posting to even though I have this page in my views folder.
app.js:
var express = require('express');
var path = require('path');
var consolidate = require('consolidate');
var bodyParser = require('body-parser');
var database = require('./database/database');
var Patient = require('./models/models').Patient;
var morgan = require('morgan');
var routes = require('./routes');
var app = express();
app.engine('html', consolidate.nunjucks);
app.set('view engine', 'html');
app.set('views', './views');
app.use(morgan('dev'));
//app.use(app.router);
app.use(routes);
app.use(bodyParser.urlencoded({ extended: false }));
app.listen(3055);
module.exports = app;
routes/index.js:
const express = require('express');
var bodyParser = require('body-parser');
var Patient = require('../models/models').Patient;
const router = express.Router();
router.get('/', function(req, res, next){
res.render('index.html');
});
router.post('/addsubject', function(req, res, next){
Patient.create(req.body).then(function(patient){
res.redirect('/profile');
}).catch(function(err){
if(error.name === "SequelizeValidationError"){
} else {
return next(err);
}
}).catch(function(error){
res.send(500, error);
});
});
router.get('/profile', function(req, res, next){
res.render('./profile.html');
});
router.get('/addsubject', function(req, res, next){
// .... do something here ..
});
module.exports = router;
I have the <form action="/addsubject" method="post"> in my index.html file.
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>dabl Demographic</title>
<body>
<h2>Add Subject</h2>
<form action="/addsubject" method="post">
<label for="fname">First Name: </label>
<input type="text" name="fname" id="fname">
<br>
<label for="sname">Second Name: </label>
<input type="text" name="sname" id="sname">
<br>
<label for="dob">dob: </label>
<input type="text" name="dob" id="dob">
<br>
<label for="laterality">Laterality: </label>
<input type="text" name="laterality" id="laterality">
<br>
<button>Submit</button>
</form>
</body>
</html>
You pass wrong function (error handling function) to the POST route.
Just remove first "err" param from the function like this:
router.post('/addsubject', function(req, res, next){
Use body-parser middleware before app.router
...
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan('dev'));
//app.use(app.router);
app.use(routes);
...
Problem solved:
}).catch(function(err){
if(error.name === "SequelizeValidationError"){
next(err); //next(err); called inide this block no more 404 error
}
User input is now succesfully passed through the body-parser.
I am creating a multiplayer game with login system. However, there is one error, which I don't know how to solve. When I run my app I get the following error:
net::ERR_CONNECTION_CLOSED.
Here is my app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/loginapp');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
// Init App
var app = express();
var http = require('http');
var server = require("http").Server(app);
var io = require("socket.io")(server);
// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout:'layout'}));
app.set('view engine', 'handlebars');
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(__dirname + 'views'));
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
app.set('port', (process.env.PORT || 3000));
io.on('connection', function(socket)
{
console.log('New connection attempt');
});
server.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
my layout.handlebar
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/bootstrap/css/bootstrap1.css' />
<link rel = "stylesheet" href="/css/style.css" />
<title>IKTSL</title>
<style>
#question_options div button:nth-child(1){
visibility: visible;
}
</style>
<script src='/socket.io/socket.io.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</head>
<body>
<script>
var socket = io.connect('https://localhost:3000');
</script>
<div class="container">
<div class="row">
<div class="col-lg-12">
{{#if success_msg}}
<div class="alert alert-success">{{success_msg}}</div>
{{/if}}
{{#if error_msg}}
<div class="alert alert-danger">{{error_msg}}</div>
{{/if}}
{{#if error}}
<div class="alert alert-danger">{{error}}</div>
{{/if}}
</div>
</div>
</div> <!-- /container -->
<div class='container-fluid'>
<div class='row'>
<div class='span12'>
<br>
<br>
<h1>I Know This Song Lyrics!</h1>
<br>
</div>
</div>
<br>
<br>
<div class='row'>
<div class='span4'>
<div class='well'>
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
{{#if user}}
<li role="presentation">Dashboard</li>
<li role="presentation">Logout</li>
{{else}}
<li role="presentation">Login</li>
<li role="presentation">Register</li>
{{/if}}
</ul>
</nav>
<h3 class="text-muted">Log in</h3>
</div>
</div>
</div>
<div class='span8'>
<div class='hero-unit'>
{{{body}}}
</div>
</div>
<div class='span5'>
<div class='users'>
<h3>Players</h3>
<div class="connectedUsers"></div>
</div>
</div>
</div>
</body>
</html>
I am just trying to console log "New connection attempt" when I starts working but that doesn't work.
I'll be grateful for any help. Thanks a lot in advance.
Firstly, I believe you can change to this (remove the additional require of http and set io to listen to server):
// Init App
var app = express();
var server = require("http").Server(app);
var io = require("socket.io").listen(server);
If your client-side is running on a different port than your server, you should change your import as well, I think. Otherwise, that piece might be fine. I don't think you need the .connect on io in var socket = io.connect(); Mine is working without it, anyway.
<script src='http://localhost:3000/socket.io/socket.io.js'></script>