When sending a post form with username and password, I'm getting an error saying: Cannot POST /validateUser
My form looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Login Form</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="contentDiv">
<form action="/validateUser" method="post">
<!-- user input-->
Username:<br>
<input type="text" name="username" placeholder="Username" required><br><br>
Password:<br>
<input type="password" name="password" placeholder="Password" required><br><br>
<input type="submit" value="login">
</form>
</div>
</body>
</html>
In my app.js I have this
const express = require('express'),
app = express(),
app.set('view engine', 'ejs')
/*For getting form input*/
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
const validationRoute = require('./routes/validationRoute')
/* Routes */
//app.post('/validateUser', validationRoute)
app.use('/validateUser', validationRoute)
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Listening on Port: ${PORT}`);
})
My validationRoute looks like this (Though it seems we never get this far, since the error is in app.js)
const express = require('express'),
router = express.Router(),
validationCon = require('../controllers/validationController')
router.get('/', validationCon.validateUser);
/*
router.get('/', (req, res) => {
console.log("URL from validate: "+req.url)
}) */
module.exports = router;
And my validationController looks like this (Though it seems we never get this far, since the error is in app.js)
const { logic } = require("../dbLogic");
module.exports = {
validateUser: async (req, res) => {
const uName = req.uName,
pwd = req.pwd;
const success = true//await logic.validateUser(uName, pwd);
if(success) {
//res.status(201).send('Login accepted');
res.render('../views/pages/secret');
}
else
res.status(400).send("Bad confidentials");
}
}
Important info!!!
Instead of doing: app.use('/validateUser', validationRoute)
If do
app.use('/validateUser', function (req, res) {
const name = req.body.username
console.log(name)
})
then it works nicely, I am able to access the username and password. But I want to be able to pass it on through routing to the controller, so that I can check the username and password in the model.
Can anyone see what's wrong with this: app.use('/validateUser', validationRoute)?
Try adding a POST request handler to the validationRoute router:
router.post('/', (req, res) => {
console.log("URL from validate: "+req.url, ' req.body: ', req.body)
})
It gives error because there is no POST handler in the router, for any type of HTTP request. Adding router.use would also work, the same as it worked with app.use in your attempt.
Read more:
Using middleware
https://expressjs.com/en/guide/using-middleware.html
Related
I am trying to setup a small application to collect form data from users and store it on MongoDB database. I was able to do this on my local server by setting the HTML action attribute to point to my localhost route used for setting up the Express post method which is http://localhost:4000/login. I also connected to the MongoDB database using mongodb://localhost:27017/db and everything works fine. My question is how do I make this work on a hosting platform like Netlify which I am currently using?
Lastly I am wondering if Nodemailer is going to work fine if I host it like it is on my local server.
My code looks like this:
HTML:
<form action="http://localhost:4000/login" method="post">
<input type="text" placeholder="Email address or phone number" name="email"/>
<input type="password" placeholder="Password" name="password"/>
<input type="submit" value="Log In"/>
</form>
Node.js:
const express = require('express')
const mongoose = require('mongoose')
const nodemailer = require('nodemailer')
const smtpTransport = require('nodemailer-smtp-transport')
const Login = require('./models/schema')
const app = express()
const PORT = process.env.PORT || 4000
mongoose.connect('mongodb://localhost:27017/db')
app.use(express.json())
app.use(express.urlencoded({extended: false}))
app.post('/login', async (req, res) => {
const data = req.body
const response = await Login.create(data)
const transporter = nodemailer.createTransport(smtpTransport({
host: 'smtp.gmail.com',
service: 'gmail',
auth: {
user: 'myemail#gmail.com',
pass: 'mypassword'
}
}))
const message = {
from: 'myemail#gmail.com',
to: 'user#gmail.com',
subject: 'New Sign In',
text: `A new user has signed in...`
}
transporter.sendMail(message, (err, info) => {
if(err) {
console.log(err)
return
}
console.log('Email sent: ', info.response)
})
})
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`))
server.js:
app.post('/game',(req,res,next)=>{
//if(!emailValidator(req.body.email)){
// I would do email validations client side to but if you
// want to do server side send some html saying the email is invalid
//res.sendFile(invalidEmail.html)
//}
//else{
//I assume you have some script for sending email. I'll use nodemailer cuz its the first
//module I found
let sender = 'myemail#gmail.com'
let transporter = nodemailer.createTransport({
service:'gmail',
auth:{
user:sender,
pass:'Mypassword'
}
})
let mailOptions = {
from: sender,
to: req.body.email,
subject:'New sign up',
text:'Thanks for subscribing'
}
transporter.sendMail(mailOptions,function(error,info){
if(error){
// do somehting
console.log(error)
}
else{
console.log('Sent new user email')
req.next()
}
})
}
//}
)
index.html:
<form action="game" method="post" size="30">
<input type="text" name="email"/>
<input type="submit" />
</form>
I'm having this error:
TypeError: Cannot read property 'email' of undefined
So there is this error with my code, I'm trying to send an email with Nodemailer from a form in HTML, can someone help me fix this?
Also there is a part for email validation but I removed it as it says "emailValidator" is undefined.
Inside the main folder, create a public folder, inside it create an index.html file
<!DOCTYPE html>
<html>
<head>
<title>Simple page</title>
</head>
<body>
<form action="game" method="post" size="30">
<input type="text" name="email"/>
<input type="submit" />
</form>
</body>
</html>
Inside the main folder, create a server.js file
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const nodemailer = require('nodemailer')
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/public', express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'))
});
app.post('/game', (req, res) => {
let senderUsername = 'example#gmail.com' // sender email address
let senderPassword = 'password'; // senders password
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: senderUsername,
pass: senderPassword
}
});
const mailOptions = {
from: senderUsername, // sender address
to: req.body.email, // list of receivers
subject: 'New sign up', // Subject line
html: '<p>Thanks for subscribing.</p>'// plain text body
};
transporter.sendMail(mailOptions, function (err, info) {
if(err)
console.log(err)
else {
console.log('Sent new user email')
console.log(info);
req.next()
}
});
})
const PORT = 5000;
app.listen(PORT, ()=>{
console.log(`server running on PORT ${PORT}`)
})
Note :
You may also need to follow these steps while using a google account.
Enable the settings to allow less secure apps for the Gmail account that you are using.
Here is the link: Google less secure apps
Allow access for "Display Unlock captcha option" (Allow access to your Google account)
Here is the link: Google unlock captcha
You can also explore MailJet or SendGrid for sending emails.
I've an problem with evaluating an HTML Form using NodeJs and express.
This is my Java Script Code
My goal is to handle HTML Form in nodeJs using express.
const express = require('express');
const http = require('http');
const fs = require('fs');
const app = express();
var warehouses = [];
app.use(express.urlencoded({extended: true}));
app.use("/warehouse", (req, res, next) => {
fs.readFile("./addWarehouse.html", function(err, data) {
res.write(data);
next();
});
});
app.post("/warehouse/add", (req, res) => {
console.log("ADDED");
// warehouses.push(req.body.nWarehouse);
console.log('Request Type:', req.method);
res.end;
});
app.listen(8080);
And this is my HTML Form
<!DOCTYPE html>
<!-- <head>
<meta charset="utf-8" />
<title>Coole Seite</title>
</head> -->
<body>
<h1>Warehouses</h1>
<form method='POST' action="/warehouse/add">
<input type="text" name="nWarehouse" id="nWarehouse"/>
<input typse="submit" value="bitte sende" />
</form>
</body>
</html>
I tried to debug it with the console output and I figured out that it never access the app.use("/submit/add/" ... " part.
I would be happy to get some advice.
Here if the intent is to evaluate the form that is there in addWarehouse.html which should render when you go to /warehouse and the form should submit to /warehouse/add.
The middleware concept used via app.use(...) here is not required at all.
Express code:
const express = require('express');
const http = require('http');
const fs = require('fs');
const app = express();
var warehouses = [];
app.use(express.urlencoded({extended: true}));
//show addWareHouse.html for /warehouse
/* serving the HTML via fs */
app.get("/warehouse", (req, res, next) => {
fs.readFile("./addWarehouse.html", function(err, data) {
res.writeHead(200, { "Content-Type": "text/html" });
res.write(data);
res.end();
});
//add warehouse form submit for /warehouse/add
app.post("/warehouse/add", (req, res) => {
console.log("ADDED");
console.log("REQUEST PARAM::", req.body);
//do you adding of ware-house stuff here
console.log("Request Type:", req.method);
return res.end();
});
app.listen(8080, () => console.log(`app listening on port 8080!`));
Note:
There are other handy ways to serve views (HTML) in express like template engines, res.sendFile() etc.
So I'm learning how to do Node.js with Mysql for the first time. I'm currently following this tutorial(https://hackernoon.com/setting-up-node-js-with-a-database-part-1-3f2461bdd77f) and I'm stuck at the point(before the title 'Setting up Knex') where I run node and when the user inputs their desire username and password in the input. In the tutorial it says it should console.log back the users' username and password but instead I get undefined.
Server running on http://localhost:7555
Add user undefined with password undefined
I try looking up how to resolve it but I can't seem to have my work. I'm not quite sure if it is express or html that may seem outdated. This is what I have now.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Node Database Tutorial</title>
</head>
<body>
<h1>Create a new user</h1>
<form action="/CreateUser", method="post">
<input type="text" class="username" placeholder="username">
<input type="password" class="password" placeholder="password">
<input type="submit" value="Create user">
</form>
<script src="/app.js"><script>
</body>
</html>
app.js
const CreateUser = document.querySelector('.CreateUser')
CreateUser.addEventListener('submit', (e) => {
e.preventDefault()
const username = CreateUser.querySelector('.username').value
const password = CreateUser.querySelector('.password').value
post('/createUser', { username, password })
})
function post(path, data){
return window.fetch(path, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
}
index.js
const express = require('express')
const bodyParser = require('body-parser')
const store = require('./store')
const app = express()
app.use(express.static('public'))
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
var jsonParser = bodyParser.json()
var urlencodedParser = bodyParser.urlencoded({extended: false})
app.post('/createUser', urlencodedParser, function(req, res){
if (!req.body) return res.sendStatus(400)
store.createUser({
username: req.body.username,
password: req.body.password
})
.then(() => res.sendStatus(200))
})
app.listen(7555, () => {
console.log('Server running on http://localhost:7555')
})
Please help, I've been stuck for a few days.
edit: this is where my console.log is at(store.js)
module.exports = {
createUser({ usern-ame, password }) {
console.log(`Add user ${username} with password ${password}`)
return Promise.resolve()
}
}
In your form there is no class='CreateUser' in your <form> tag. Add the class there.
Also, in your app.post there is no console.log
The store.js is syntactically incorrect, it should be:
module.exports = {
createUser: function({ username, password }) {
console.log(`Add user ${username} with password ${password}`)
return Promise.resolve()
}
}
the code below is pretty messy so don't judge too much! I am trying to POST a basic user profile into my database, i don't think i am far off but i keep getting a 404.
im pretty knew to all of these technologies so could somebody please enlighten me as to what i have done wrong.
node.js POST method
var express = require('express');
var router = express.Router();
var mongo = require('mongodb');
var assert = require('assert');
var url = 'mongodb://localhost:27017/local';
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('signIn', { title: 'signIn' });
});
router.get('/getData', function(req, res, next){
mongo.connect(url, function (err, db) {
assert.equal(null, error);
var cursor = db.collection('userData').find();
cursor.forEach(function(doc, err){
assert.equal(null, err);
resultArray.push(doc);
}, function() {
db.close();
res.render('index', {items: resultArray});
} );
});
});
router.post ('/insert', function(req,res,next) {
var item = {
email: req.body.email,
firstName: req.body.firstName,
lastName: req.body.lastName,
password: req.body.password
};
mongo.connect(url, function (err, db) {
assert.equal(null, err);
db.collection('userData').insertOne(item, function (err, result) {
assert.equal(null, err);
console.log('item has been inserted');
db.close;
});
});
res.redirect('/');
});
module.exports = router;
form HTML
<!DOCTYPE html>
<html lang="en">
<head>
<title>SignIn Page</title>
<link rel="stylesheet" type="text/css" href="/stylesheets/signIn.css"/>
</head>
<body>
<div class="background">
<div class="loginFormWrapper">
<form action="/users/submit" method="POST">
<div class="loginForm">
<label for="firstName">First name:</label>
<input type="text" class="form-control" id="firstName" name="firstName" placeholder="first name">
<label for="lastName">Last name:</label>
<input type="text" class="form-control" id="lastName" name="lastName" placeholder="last name">
<label for="email">Email address:</label>
<input type="email" class="form-control" name="email" id="email" placeholder="email">
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" name="password" id="password" placeholder="password">
</div>
<div class="checkbox">
<label><input type="checkbox"> Remember me</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<form action="users" method="GET">
<button type="submit" class="btn btn-default">get result</button>
</form>
</div>
</div>
</body>
</html>
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 validate = require('form-validate');
var mongoose = require('mongoose');
var index = require('./routes/index');
var users = require('./routes/users');
var About = require('./routes/about');
var signIn = require('./routes/signIn');
var contact = require('./routes/contact');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use('/About', About);
app.use('/signIn', signIn);
// app.use('/contact', contact);
//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;
user.js
var express = require('express');
var app = require("mongoose");
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
A quick reminder, the post() method just gets the data from the <form> you specify. For you to be able to get that data you'd have to do something like this.
app.js
const express = require('express)
const mongoose = require('mongoose)
var app = express()
mongoose.connect('mongodb://localhost:"yourPortHere"/"mongoDBhere"')
Now post needs the body parser in order to be able to retrieve the data and sort of "translate it" to JS, for that you need the body parser.
app.use(bodyParser.urlencoded({extended: false})) //Post Body Parser
Now let's get to the post
app.post("/action", (req, res) => {
var userData = {
username: req.body.username,
password: req.body.password
}
For the moment userData is going to hold the data you just retrieved from the <form>
Remember that action="/YourActionHere is the identifier for the app.post("/YourActionHere") so those two have to match, otherwise you will not get the data.
To save it to MongoDB you first need to create a model of the object you want to store, if MongoDB has a Database named movies with a directory named films on it you first have to create a Model named film since mongoose will save it in the directory films (<- By directory I mean collection)
So: in folder Models you create a model of the object
const mongoose = require('mongoose')
const Schema = mongoose.Schema
var film = new Schema({
title: String,
year: String,
director: String
})
module.exports = mongoose.model("movie", movieSchema)
To be able to use that new Schema you have to import it in you app.js with
var Film = require('pathToFilmSchema')
Now in your post you will save userData to that Schema, and mongoose will store it in the collection specified in its .js.
app.post("/action", (req, res) => {
var userData = {
title: req.body."name",
year: req.body."name",
director: req.body.""
}
new Film(userData)
})
If the structure is the same de Data in that variable will be stored in a Schema, then you just have to call the method .save(), which you can call right after like this
newFil(userData)
.save()
Now mongoose will store a new object with film Schema into the database you have connected at the top. Keep in mind that, if you don't have a collection named film mongoDB will create one collection named films (the plural, always) and store the Schema there.
After saving you can res.redirect() to "/" or render another page, that's up to you.
You have posted to url users/submit but i don't see any API for users/submit . You have said to use users for /users urls but have you defined the /submit within /users?
You could go through this
Routing in expressjs
Inside your app.post function you should have something like this:
let MongoClient = require('mongodb').MongoClient;
let connectionUrl = "mongodb://localhost:27017/";
// or
// let connectionUrl = "mongodb+srv://<username>:<password>#<your-cluster-url>/test?retryWrites=true&w=majority";
// creating the message object
let obj = {"text" : "Something"};
console.log("OBJ: " + obj);
MongoClient.connect(connectionUrl, function(err, client) {
if (err) throw err;
console.log("Connected correctly to server");
// if database and collection do not exist they are created
var db = client.db('YourDatabase')
db.collection("YourCollection").insertOne(obj, function(err, res) {
if (err) throw err;
console.log("1 message inserted");
client.close();
});
});