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.
Related
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.
Im using express, node, bodyParser to pull information from a contact form and post it to the terminal. When I run the code and access my demo site through LocalHost:3000, upon submitting, my input items are not showing up in the terminal.
I've tried changing the form attributes action="send" action="/send" action="/"
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const nodemailer = require('nodemailer');
const app = express();
// View engine setup
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Static folder
app.use('/public', express.static(path.join(__dirname, 'public')));
/ Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.render('contact', { layout: false });
});
app.post('/send', (req, res) => {
console.log(res.body);
});
//Form HTML code
<form action="send" method="POST">
<input name="name" type="text" id="name" placeholder="NAME: First & Last">
<input name="email" type="text" id="email" placeholder="EMAIL:">
<textarea name="text" id="text" cols="30" rows="10" placeholder="QUESTION OR INQUIRY:"></textarea>
<br>
<button type="submit">Submit</button>
</form>
Have you tried console logging the req instead of the res for the app.post?
If you are doing console.log(req.body) then this should output a long json object. If this is not happening, then you are not hitting the url.
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const nodemailer = require('nodemailer');
const app = express();
// View engine setup
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Static folder
app.use('/public', express.static(path.join(__dirname, 'public')));
// Body Parser Middleware
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.render('contact', { layout: false });
});
app.post('/send', (req, res) => {
console.log(res.body);
});
The problem is in your html code. I have made some changes, Try this.
//Form HTML code
<form action="http://localhost:9000/send" method="POST">
<input name="name" type="text" id="name" placeholder="NAME: First & Last">
<input name="email" type="text" id="email" placeholder="EMAIL:">
<textarea name="text" id="text" cols="30" rows="10" placeholder="QUESTION OR INQUIRY:"></textarea>
<br>
<button type="submit">Submit</button>
</form>
I have two ejs in my views folder
I have created very simple ejs to see if I can send the variable from one ejs to another ejs.
a.ejs in veiws file
<form name="input" action="\home" method="post">
<input type='checkbox' checked>Cheese
<input type="submit" value="Submit" href="validation.ejs">
</form>
b.ejs has
<h1><% post my variable here%></h1>
in my node js this is what i did
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('index', { title: 'EJS Demo' });
});
app.post('/', (req, res) => {
const a = req.body.a;
res.get('index2',a);
});
app.listen(3000, () => {
console.log('Listening....');
});
i think the post has to do something in here...
I think you need to submit a value from form1 in page1 and pass that variable to page2
if thats the case you can do like this
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.set('view engine', 'ejs');
// send the page1 to the user
app.get('/', (req, res) => {
res.render('page1', { title: 'EJS Demo' });
});
//capture the submit from the user and then send another page
//to the user
app.post('/submitForm', (req, res) => {
const a = req.body.valueFromA;
res.render('page2',a);
});
app.listen(3000, () => {
console.log('Listening....');
});
<form name="input" action="\home" method="post">
<input type='checkbox' checked>Cheese
<input type="submit" value="Submit" href="validation.ejs">
</form>
<!-- page1 form1 -->
<html>
<head>
<title> <& title &> </title>
</head>
<form action='/submitForm' method='post'>
<input type='text' value='' name='valueFromA' />
<input type='submit' />
</form>
</html>
<!-- page2 ejs -->
<html>
<body>
<p> <% value %> </p>
</body>
</html>
b.ejs has
<h1><% post my variable here%></h1>
in my node js this is what i did const
Please can you help me out, for some reason I am not able to post and am getting a "cannot POST /api/create" and when inspecting the page a 404 error is shown.
Here is my index.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mainRouter = require('./mainRouter.js');
var todoRoutes = require('./todoRoutes.js');
//tell express to use bodyParser for JSON and URL encoded form bodies
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
//mouting our routers
app.use('/', mainRouter);
app.use('/todo',todoRoutes);
app.listen(3000);
console.log("Express server running on port 3000");
And the corresponding todoRoutes.js file is where I require the post method:
var express = require('express');
var todoRoutes = express.Router();
var todoList = []; //to do list array
todoRoutes.get('/', function(req, res) {
res.sendFile(__dirname + '/views/todo/index.html');
});
todoRoutes.get('/create', function(req, res) {
res.sendFile(__dirname + '/views/todo/create.html');
});
todoRoutes.get('/api/list', function(req, res) {
res.json(todoList); //respond with JSON
});
todoRoutes.get('/api/get/:id',function(req, res){
res.json(todoList[req.params.id]);
});
todoRoutes.post('/api/create', function(req, res){
console.log("Creating the following todo:", req.body.todo);
todoList.push(req.body.todo);
res.send({redirect: '/api/list'});
});
and here is the corresponding html file:
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Todo List: Create</title>
<meta charset="utf-8" />
</head>
<body>
<form action = "/api/create" method="post">
<div>
<label for="todo">Enter your new Todo:</label>
<input type="text" id="todo" name="todo">
</div>
<div class="button">
<button type="submit">Add</button>
</div>
</form>
</body>
</html>
If I put a console.log("") in the POST function of the todoRoutes.js file it will not be displayed, indicating that the function does not even get executed.
Any help will be very much appreciated.
You need to POST to /todo/api/create, based on your current route handling:
<form action = "/todo/api/create" method="post">
This is my server.js file:
var express = require("express");
var bodyParser = require("body-parser");
var controllers = require('./controllers');
var app = express();
controllers.init(app);
app.set('view engine', 'vash');
app.use(bodyParser());
app.use(express.static(__dirname + "/public"));
app.listen(5000);
This is my index.js code in controllers folder:
(function(controllers){
var homeController = require('./homeController');
controllers.init = function(app){
homeController.init(app);
};
})(module.exports);
This is my homeController.js code:
(function(homeController){
homeController.init = function(app){
app.get('/', function(req, res){
res.render('index', {title: "The Board"});
});
app.post("/", function(req, res){
console.log(req.headers);
console.log(req.body);
});
};
})(module.exports);
And this is my HTML:
#html.extend('layout', function(model){
#html.block('body', function(model){
#if(model.error){
<p class="text-error">Error occurred: #model.error</p>
}
<div class="row">
<form action="/" method="post">Enter your name:
<input type="text" name="userName" placeholder="..." />
<br>
<button type="submit">Submit</button>
</form>
</div>
})
})
When I make the post action req.body is undefined. How can I solve this problem?
Move app.use(bodyParser()); before route declaration controllers.init(app);