Req.flash(errors) Not Displaying -NodeJS 5.7.0 - javascript

I am trying to make it so when a user enters an email that is already in the db to let the user know that that account email is already registered.
I am getting the correct error from mongo db but I dont want to display all that junk. I want it to just display my error on my signup page in the form saying something like "This email address is registered already".
MongoDB Response:
MongoError: E11000 duplicate key error index: jcommerce.users.$email_1 dup key: { : "james12345#gmail.com" }
at Function.MongoError.create (C:\jcommerce\node_modules\mongodb-core\lib\error.js:31:11)
at toError (C:\jcommerce\node_modules\mongodb\lib\utils.js:114:22)
at C:\jcommerce\node_modules\mongodb\lib\collection.js:616:23
at handleCallback (C:\jcommerce\node_modules\mongodb\lib\utils.js:96:12)
at C:\jcommerce\node_modules\mongodb\lib\bulk\unordered.js:470:9
at handleCallback (C:\jcommerce\node_modules\mongodb\lib\utils.js:96:12)
at resultHandler (C:\jcommerce\node_modules\mongodb\lib\bulk\unordered.js:417:5)
at commandCallback (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:936:9)
at Callbacks.emit (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:116:3)
at null.messageHandler (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:282:23)
at Socket.<anonymous> (C:\jcommerce\node_modules\mongodb-core\lib\connection\connection.js:273:22)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at readableAddChunk (_stream_readable.js:153:18)
at Socket.Readable.push (_stream_readable.js:111:10)
at TCP.onread (net.js:529:20)
Route Class
var router = require('express').Router();
var User = require('../models/user')
router.get('/signup', function (req, res, next) {
res.render('accounts/signup', {
errors: req.flash('errors')
});
});
router.post('/signup', function(req, res, next) {
var user = new User();
user.profile.name = req.body.name;
user.email = req.body.email;
user.password = req.body.password;
// Validate
User.findOne({email: req.body.email}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', 'Account with that email address already exists');
return res.redirect('/signup');
}
else {
// save user to database
user.save(function(err, user) {
if (err) {
return next(err);
}
return res.redirect('/');
});
}
}); // Mongoose method find one document in db
});
module.exports = router;
EJS
<% layout('layout') -%>
<div class="row">
<div class="col-lg-6 col-md-offset-3">
<% if (errors.length > 0) { %>
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<%= errors %>
</div>
<% } %>
<form method="post">
<h1> Signup! </h1>
<div class="form-group">
<label="name"> Name: </label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<label="name"> Email: </label>
<input type="email" class="form-control" name="email">
</div>
<div class="form-group">
<label="name"> Password: </label>
<input type="passwod" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-success"> Submit</button>
</form>
</div>
</div>
Server.js AKA app.js
// Require library we want to use
var express = require('express');
var morgan = require('morgan');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var ejs = require('ejs');
var engine = require('ejs-mate');
var session = require('express-session');
var cookieParser = require('cookie-parser'); // parses cookies and put it on the request object in the middleware
var flash = require('express-flash');
var User = require('./models/user');
// App is reffering to express objects, bc we want to use express objects
var app = express();
mongoose.connect('mongodbconnectionstring', function (err) {
if (err) {
console.log(err);
}
else
{
console.log("Connected to the database");
}
});
//Middleware - logs requests in cmd
app.use(express.static(__dirname + '/public'));
app.use(morgan('dev'));
app.use(bodyParser.json()); // Express can parse data format
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());
app.use(session({
resave: true,
saveUninitialized: true,
secret: "James#####"
}));
app.use(flash());
app.engine('ejs', engine)
app.set('view engine', 'ejs');
// body parser takes the body of request and parses it -> Format encoded or raw data
var mainRoutes = require('./routes/main');
var userRoutes = require('./routes/user');
app.use(mainRoutes); // Express is using main routes
app.use(userRoutes);
// Listen on port number 3000 ,
app.listen(3000, function (err) {
if (err) {
throw err;
}
console.log("Server is Running on port 3000");
});

The error stems from this line:
user.email = req.body.email;
This occurs because req.body.email is undefined which means the email is not unique. You should verify that the request to /signup is sent with data from the client.

I just had to check if
exisitinguser !== null
if (existingUser !== null)

Related

Node.js login form via MongoDB

Earlier, I had a site with login forms and such but no database connectivity. I've now connected it to one with mongodb and have gotten some things working. I'm able to use RESTED to send requests and create accounts and validate accounts within the database.
I'm wondering, how would I be able to implement this functionality inside of a form? Where it would take the form details, query it through the database, and login if successful? Same with registering.
Here's the index:
const config = require('config');
var Joi = require('joi');
Joi.objectId = require('joi-objectid')(Joi);
const mongoose = require('mongoose');
const users = require('./routes/users');
const auth = require('./routes/auth');
var express = require("express");
var hbs = require('express-handlebars');
var app = express();
var bodyParser = require('body-parser');
if (!config.get('PrivateKey')) {
console.error('Error: PrivateKey is not defined.');
process.exit(1);
}
mongoose.connect('mongodb://localhost/airbnb')
.then(() => console.log('Now connected to MongoDB!'))
.catch(err => console.error('Something went wrong', err));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'hbs');
app.engine('hbs', hbs({
extname: 'hbs',
defaultLayout: 'main',
layoutsDir: __dirname + '/views/layouts',
partialsDir: __dirname + '/views/partials/'
}));
app.use('/static', express.static('public'));
app.use(express.json());
app.use('/api/users', users);
app.use('/api/auth', auth);
var HTTP_PORT = process.env.PORT || 8080;
// call this function after the http server starts listening for requests
function onHttpStart() {
console.log("Express http server listening on: " + HTTP_PORT);
}
// setup a 'route' to listen on the default url path (http://localhost)
app.get("/", function (req, res) {
res.render('home', {layout: false})
});
// setup another route to listen on /about
app.get("/roomList", function (req, res) {
res.render('roomList', {layout: false})
});
app.get("/dashboard", function (req, res) {
res.render('dashboard', {layout: false})
});
// setup http server to listen on HTTP_PORT
app.listen(HTTP_PORT, onHttpStart);
here's user.js
// require mongoose and setup the Schema
var mongoose = require("mongoose");
var Joi = require('joi');
const joiObjectid = require("joi-objectid");
// connect to the localhost mongo running on default port 27017
mongoose.connect("mongodb://localhost/airbnb");
// define the company schema
// register the Company model using the companySchema
// use the web322_companies collection in the db to store documents
var User = mongoose.model('User', new mongoose.Schema({
email: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
password: {
type: String,
required: true,
minlength: 6,
maxlength: 55555
}
}));
// validate
function validateUser(user) {
const schema = Joi.object({
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(6).max(55555).required()
});
return schema.validate(user);
}
// export
exports.User = User;
exports.validate = validateUser;
here's users.js
const jwt = require('jsonwebtoken');
const config = require('config');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const { User, validate } = require('../models/user');
const express = require('express');
const router = express.Router();
router.post('/', async (req,res) => {
const { error } = validate(req.body);
if (error) {
console.log(req.body.email);
console.log(req.body.password);
return res.status(400).send(error.details[0].message);
}
let user = await User.findOne({ email: req.body.email });
if (user) {
return res.status(400).send('That user already exists!');
} else {
user = new User(_.pick(req.body, ['name', 'email', 'password']));
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const token = jwt.sign({_id: user._id }, config.get('PrivateKey'));
res.header('x-auth-token', token).send(_.pick(user, ['_id', 'name', 'email']));
}
});
module.exports = router;
here's auth.js
const config = require('config');
const jwt = require('jsonwebtoken');
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const { User } = require('../models/user');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let user = await User.findOne({ email: req.body.email });
if (!user) {
return res.status(400).send('Incorrect email or password');
}
const validPassword = await bcrypt.compare(req.body.password, user.password);
if (!validPassword) {
return res.status(400).send('Incorrect email or password');
}
const token = jwt.sign({_id: user._id }, config.get('PrivateKey'));
res.send(token);
});
function validate(req)
{
const schema = Joi.object({
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(6).max(55555).required()
});
return schema.validate(req);
}
module.exports = router;
This is what my signup modal looks like currently:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Registration</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form name="regForm" method="get" action="dashboard" onsubmit="return validateSignupForm()">
<div class="form-group mb-0">
<label for="formGroupEmail"></label>
<input type="email" class="form-control" id="formGroupEmail" placeholder="Email address"
name="signupEmail">
</div>
<div class="form-group mb-0">
<label for="formGroupPassword"></label>
<input type="password" class="form-control" id="formGroupPassword" placeholder="Password"
name="signupPassword">
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Sign up" class="btn btn-danger">
</div>
</form>
</div>
</div>
</div>
function validateSignupForm() {
var signupEmail = document.forms["regForm"]["signupEmail"].value;
var signupPassword = document.forms["regForm"]["signupPassword"].value;
if (signupPassword.match(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,20}$/)) {
return true;
}
else {
alert('Password must be between 6 and 20 characters and contain at least one number and uppercase letter');
return false;
}
}
Seems like that's a lot of efforts you are putting up with all that code, whereas you can simply use passport.js specifically passport-local-mongoose to get the register/login working with few lines of code. For submitting the form, You'll have to use something like ajax which can send requests to your backend server.

req.body is returning a default value and not my POST request

I'm sure I am making a small error and I cannot find the answer in other questions. Basically every time I try to make a POST request the console is displaying "{}" instead of the value from the post request. I am using EJS and Node.js to deal with this POST request.
Here's the code from the ejs file
<label> My Favourite Saying</label>
<form action ="/users/dashboard" method ="POST">
<div class = "form-group">
<input
type="name"
id="favSaying"
class="form-control"
placeholder = "Enter phrase here"
/>
</div>
<small id="FavSayingInst" class="form-text text-muted">
Enter a phrase to have it stored for the next time you login.
</small>
<button type="submit" class="btn btn-dark mt-2">Submit</button>
</div>
</form>
Here is the code from the handler file
//Handle the fav saying
router.post('/dashboard', (req,res) => {
console.log(req.body);
console.log("test123");
//User.findOneAndUpdate({email:'tester2#gmail.com', favSaying})
req.flash('store_msg', 'Your phrase has been stored!');
res.redirect('/views/dashboard');
});
I've already added the body parser so I know it's not that, :
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const app = express();
const mongoose = require('mongoose');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
require('./config/passport')(passport);
//EJS
app.use(expressLayouts);
app.set('view engine','ejs');
//DB Config
const db = require('./config/keys').MongoURI;
//Connect to Mongo
mongoose.connect(db, { useNewUrlParser: true })
.then(() => console.log('MongoDB connected...'))
.catch(err => console.log(err));
//Bodyparser
app.use(express.urlencoded({extended: false}));
//Session
app.use(session({
secret: 's',
resave: true,
saveUninitialized: true
}));
//Passport
app.use(passport.initialize());
app.use(passport.session());
//Connect flash
app.use(flash());
//Vars
app.use((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.store_msg = req.flash('store_msg');
next();
});
//Routes
app.use('/', require('./routes/index2')); //The first comment is where the webpage routes to, the second is the js file
app.use('/users', require('./routes/users'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on Port ${PORT}`));
Does anyone know why I would be getting "{}" instead of my values? I have
The input element should have a name attribute to transmit the data into the request.
You should have 'name' attribute in your input tags.
You need to check your response.
// POST method route
router.post('/', function (req, res) {
res.send(req.body);
});
Try it.
You have to fix this.
<input type="text" name="name" ...>
That's why, <input> tag type don't have name.
And name is post body field key.

Error: Can't set headers after they are sent. authentication system

I want to write a little authentication app with mysql connection and I get this error all the time, but I need it this way.
I want to send a response if the client gets /admin if he is not an admin and if he is, admin should be rendered.
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');
const admin = require("./routes/admin");
const session = require("express-session");
var app = express();
app.set("trust proxy", 1);
app.use(session({
secret: "asdf",
resave: false,
cookie: {
maxAge: 120000
},
saveUninitialized: false
}));
function checkIfLoggedin(req,res,next){
if(!(req.originalUrl === "/") && !req.session.loggedIn){
res.redirect('/');
return;
}
next();
};
// 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(checkIfLoggedin);
app.use('/', index);
app.use("/admin", admin);
// 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();
const bcrypt = require('bcrypt-nodejs');
var dbPassword;
import mysql from "mysql";
//
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', {});
});
router.post('/', function(req,res,next) {
console.log("1");
const enteredUsername = req.body.username;
const enteredPassword = req.body.password;
const con = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
con.query('SELECT * FROM users WHERE username = ?;', [`${enteredUsername}`], (error, results, fields) => {
if (results.length > 0) {
console.log("2");
console.log(error);
let dbPassword = results[0].password;
bcrypt.compare(enteredPassword, dbPassword, (err,response) => {
console.log(err);
console.log(response);
console.log("3");
if (response == true) {
req.session.user = {
userId: results[0].userId,
username: results[0].username,
isAdmin: results[0].isAdmin,
};
req.session.loggedIn = true;
console.log("file");
if (req.session.user.isAdmin) {
res.redirect("/admin");
}
else{
res.redirect("/file/" + req.session.user.userId);
}
}
else{
req.session.loggedIn = false;
console.log("false");
res.send("Wrong password");
}
});
}
else{
res.send("Wrong Data");
}
});
});
module.exports = router;
admin.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
}
res.render("admin");
});
module.exports = router;
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>Costufi</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="stylesheets/materialize.min.css" media="screen,projection"/>
</head>
<body>
<main>
<center>
<div class="container">
<div class="z-depth-2" style="display: inline-block; padding: 20px 50px 10px 50px; margin-top: 15%;">
<form class="col s12" action="/" method="post">
<div class="row">
<h4>Login</h4>
<div class="input-field col s12">
<input type="text" name="username" id="username" class="validate">
<label for="username">Username</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="password" name="password" id="password" class="validate">
<label for="password">PassworD</label>
</div>
</div>
<div class="row">
<button class="left btn waves-effect waves-light indigo darken-2" type="submit" name="send">Login
<i class="material-icons right">send</i>
</div>
</form>
</div>
</div>
</center>
</main>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/materialize.min.js"></script>
</body>
</html>
This error is caused when you attempt to send more than one response to the same request. I didn't study all the places in your code, but here's one obvious case:
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
}
res.render("admin");
});
If your if test is true, then you end up doing both a res.send() and a res.render(). The res.render() triggers the warning because you've already sent a response on this connection and can't send another one. You should change it to this:
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
} else {
res.render("admin");
}
});

req.body is empty { } after form post in node application

Question/Problem
My req.body is undefined when I post form data... This is strange because I have multiple other pages with forms where I post data the same way but all of a sudden I am getting this issue and I do not know why. This does seem to be a common problem but I can't find a fix that works for me.
What I have tried so far...
Checked console.log(req.is('json')) but it is false and I do not know what to do with this information - I feel like this might be the source of my problem. It doesn't look like I can set form data to json
I have other forms which I coded in a similar manner that work
Included 'body-parser'/app.use(bodyParser.json());... see the above point
Tried using app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
Made sure I have a name property for each input field
EDIT: app.use(bodyParser.urlencoded()); does not work
Code
<form action="/changePassword" method="post" onsubmit="event.stopPropagation(); return passwordChange(this);" enctype="application/x-www-form-urlencoded" novalidate="">
<input id="password1" placeholder="password" name="password1" maxlength="30" class="form-control input-sm chat-input" type="password">
<input id="password2" placeholder="confirm password" name="password2" maxlength="30" class="form-control input-sm chat-input" type="password">
<input id="changePassword" value="Change Password" type="submit">
</form>
app.post('/changePassword', users.changePassword);
module.exports.changePassword = function(req, res){
console.log(req.is('json')); // false and req.body is undefined
...
...
res.redirect('/');
});
Let me know if additional code is needed.
EDIT: Not sure if this is worth mentioning but I had other problems which again I did not have with other pages. When I was trying to validate the passwords, return false; would not prevent the page from posting/executing. I had to include event.stopPropagation().
Additional Code:
./bin/www
!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('app:server');
var http = require('http');
var express= require('express');
/**
* Get port from environment and store in Express.
*/
var port = parseInt(process.env.PORT, 10) || 3000;
app.set('port', port);
/**
* Create HTTP server.
*/
// var server = http.createServer(app);
//var server = app;
/**
* Listen on provided port, on all network interfaces.
*/
app.use((err, req, res, next) => {
console.log(err.stack || err.message);
if (res.headersSent)
return next(err)
res.status(500).send('Internal Server Error')
})
app.listen(port);
app.on('error', onError);
app.on('listening', onListening);
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error('Port ' + port + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error('Port ' + port + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
debug('Listening on port ' + server.address().port);
}
app.js
/*jslint node:true */
/*global $, jQuery, alert*/
"use strict";
var express = require('express');
var path = require('path');
var fs = require('fs');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var expressSession = require('express-session');
var mongoose = require('mongoose');
var mongoStore = require('connect-mongo/es5')({ session: expressSession });
var passport = require('passport');
var debug = require('debug')('app:server');
var uriUtil = require('mongodb-uri');
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
var assert = require('assert');
mongoose.Promise = global.Promise;
var MONGOLAB_URI = ****;
var mongooseUri = uriUtil.formatMongoose(MONGOLAB_URI);
var mongoConnection = mongoose.connect(MONGOLAB_URI, function (err, db) {
if (err) {
console.log('Unable to connect to MongoDB: ', err);
} else {
console.log('Connection has been established...');
}
});
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
console.log("__dirname: " + __dirname);
app.use(expressSession({
secret: 'RCNEfyBUAcHnPeQxFWyBTr',
cookie: { maxAge: 60*60*1000 },
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
require('./routes/index')(app, conn);
// 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;
exports.mongoConnection = mongoConnection;
index.js
module.exports = function (app, conn) {
...
app.post('/signup', users.signup);
app.post('/login', users.login)
app.post('/changePassword', users.changePassword);
app.post('/password', users.password); // send new password
app.post('/user/create_test', users.create_test);
app.post('/user/calculatesubjects', users.calculate_subjects);
app.post('/user/calculatetopics', users.calculate_topics);
app.post('/test/:username/:testid/:noq/:quesnum', users.answer_selected);
// Admin posts
app.post('/admin/update_subjects_topics', admin.update_subjects_topics);
app.post('/admin/add_question', admin.add_question);
}
passwordChange function
function passwordChange(form)
{
if(form.password1.value != "" && form.password1.value == form.password2.value) {
if(form.password1.value.length < 6) {
alert("Error: Password must contain at least six characters!");
form.password1.focus();
return false;
}
re = /[a-z]/;
if(!re.test(form.password1.value)) {
alert("Error: password must contain at least one lowercase letter (a-z)!");
form.password2.focus();
return false;
}
} else {
alert("Error: Please check that you've entered and confirmed your password!");
form.password2.focus();
return false;
}
return true;
}
It does sound like the problem is that the form is not being sent in JSON. By default html forms are sent as urlencoded (which you specified). Unless you are sending the form via javascript and specify json you should be using bodyParser.urlencoded:
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded());
I am confused to how other forms made similarly are working. The forms still can be sent via json if you use something like jQuery to send them via a script (and not with native html).

NodeJS express Post form - action always 404

No matter what link I declare in the action of my form, it always returns an 404 error. if I change the method to get, it doesn't.
I want to use post because i'm trying to get the data from my input fields and post it in my mongedb database:
HTML:
<form class="container-fluid searchContainer" action="/active" method="post">
<div class="col-xs-6">
<div class="form-group">
<label for="businessUnit">Business unit</label>
<input type="text" ng-model="businessUnit" id="businessUnit" name="businessUnit" class="form-control"/>
</div>
<div class="form-group">
<label for="tenderId">Tender ID</label>
<input type="text" name="tenderID" ng-model="tenderId" id="tenderId" class="form-control"/>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="tenderDate">Tender Bidding Date</label>
<input type="date" ng-model="tenderDate" name="tenderDate" id="tenderDate" class="form-control"/>
</div>
<div class="form-group">
<label for="therapyArea">Therapy area</label>
<input type="text" ng-model="therapyArea" name="therapyArea" id="therapyArea" class="form-control"/>
</div>
</div>
<div class="col-md-12 text-right">
<input type="submit" id="btnCreate" value="Create" class="btn btn-primary" >
</div>
</form>
JAVASCRIPT:
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 active = require('./routes/active');
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: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/active', active);
// 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;
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tenders');
var db = mongoose.connection;
db.on('error', function(err) {
console.log('connection error', err);
});
db.once('open', function() {
console.log('connected.');
});
var Schema = new mongoose.Schema({
TenderID: String,
TenderDate: String,
BusinessUnit: String,
TherapyUnit: String
});
var Tender = mongoose.model('Tender', Schema);
app.post('/active', function(req, res) {
new Tender({
TenderID: req.body.tenderID,
TenderDate: req.body.tenderDate,
BusinessUnit: req.body.businessunit,
TherapyUnit: req.body.therapyUnit
}).save(function(err, doc) {
if (err) res.json(err);
else res.send('Succesfully insterted')
})
});
Because you define your 404 route handler before you define app.post('/active'), express evaluates the 404 rule first and returns it. Your POST /active route never gets evaluated. To fix this you need to give Express your POST /active route before your 404 route (which should always be your last route).
Unless you have an equivalent POST /active route defined in the file ./routes/active, the line
app.use('/active', active);
won't fix this problem even though it is evaluated before your 404 route. You can read more about app.use() vs app.get|post|etc() in the express docs.
Express evaluates rules in the order they are passed to it via use() or get|post|delete|etc()
You have defined get route in your server. Try to change the
app.get('/active',function(req,res){
into
app.post('/active',function(req,res){
In this way, you will respond to a post request from the browser.

Categories