Empty object in post request Express.JS - html

I'm working with Express v^4.18.2, I have some routing and controller files and an html form with post method. When I make the post, I try to get the server to show me the req.body sent in the request through the console, but I get an empty object. It should be noted that I am following a tutorial and I do it step by step. Could someone with more knowledge of Express tell me what is going on?
Routes.js
import { Router } from "express";
import dashBoardObject from "../Controller/DashboardsController.js";
import { DashboardContoroller} from "../Controller/DashboardsController.js";
const router = Router();
const { formDashboardController,
postFormDashboardController,
putDashboardContoller
} = dashBoardObject;
router
.get('/DashBoard', DashboardContoroller)
.get('/DashBoard/createdDasboard', formDashboardController)
router
.post('/DashBoard/createdDasboard', postFormDashboardController)
router
.put('/DashBoard/updateDashboard', putDashboardContoller)
export default router;
As you can see, in the routes I try to destruct the object that I get from the controller.
Controller.js
const dashBoardObject = {};
export const DashboardContoroller= (req, res) =>{
res.send(`indicators/Indicators`);
}
dashBoardObject.formDashboardController = (req, res) =>{
res.render(`indicators/Indicators`);
}
dashBoardObject.postFormDashboardController = (req, res) =>{
// let values = Object.values();
console.log(`request: ${req.body}`);
res.send(`<h3> CREATED! 🆗 ${req.body} </h3>`);
}
dashBoardObject.putDashboardContoller = (req, res) =>{
res.send(`<h3> UPDATED! 🆗 </h3>`);
}
export default dashBoardObject;
HTML
<div style="display: flex; flex-direction: column; justify-content: center;">
<div>
<form action="/DashBoard/createdDasboard" method="POST">
<div class="mb-2 row">
<label for="" class="col-sm-2 col-form-label">Titulo</label>
<div>
<input class="form-control" placeholder="Titulo" type="text" autofocus>
</div>
</div>
<div class="mb-2 row">
<label for="" class="col-sm-2 col-form-label">Titulo</label>
<div>
<input class="form-control" name="Title" placeholder="Titulo" type="text">
</div>
</div>
<div class="mb-2 row">
<label for="" class="col-sm-2 col-form-label">enviar</label>
<div>
<button class="btn btn-primary" >Actualizar</button>
</div>
</div>
</form>
</div>
This is what I get in the browser:

If req.body is empty, you should add a middleware on top of your router:
router.use(express.urlencoded())
Also, to correctly show the object in the html response:
res.send(`<h3> CREATED! 🆗 ${JSON.stringify(req.body)} </h3>`);

Related

How to pass data from html client to NodeJS server?

I would like to send some data from client to NodeJS server using POST method.
Below is my part of html code.
<form action="http://localhost:8080/data/name/:name/ssn/:ssn" method="post" id="signup">
<h1>Personal info post example</h1>
<div class="field">
<label for="name">Name:</label>
<input type="text" id="name" placeholder="Enter your fullname" />
<small></small>
</div>
<div class="field">
<label for="ssn">SSN:</label>
<input type="text" id="ssn" placeholder="Enter your SSN" />
<small></small>
</div>
<button type="submit">Submit</button><br><br>
</form>
Below is my part of server.js.
I tried to print out everything that I can think of what I can.
I wrote down the results as comments as well.
This is the result when I enter 'a' for the name and 'b' for the ssn and submit it.
app.post('/data/name/:name/ssn/:ssn', function(req, res) {
console.log('req.query: ', req.query); // {}
console.log('req.query.name: ',req.query.name); // undefined
console.log('req.query.ssn: ',req.query.ssn); // undefined
console.log('req.params: ',req.params); // { name: ':name', ssn: ':ssn' }
console.log('req.params.name: ',req.params.name); // :name
console.log('req.params.ssn: ',req.params.ssn); // :ssn
});
When I type 'a' and 'b' into search boxes and hit the submit button, the web browser starting to load but never ends and my VSC shows the result.
Can anyone help me what I need to fix?
looks like you're mixing req.params and req.query, while you actually need req.body
try this:
add this to server.js (you need to install body-parser):
const bodyParser = require('body-parser');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// parse application/json
app.use(bodyParser.json());
app.post('/data', function(req, res) {
console.log('req.body: ', req.body);
const {name, ssn} = req.body;
console.log('name: ', name);
console.log('ssn: ', ssn);
res.json(req.body);
});
and change HTML form (add name attribute, that's your data):
<form action="http://localhost:8080/data" method="post" id="signup">
<h1>Personal info post example</h1>
<div class="field">
<label for="name">Name:</label>
<input type="text" id="name" name="name" placeholder="Enter your fullname" />
<small></small>
</div>
<div class="field">
<label for="ssn">SSN:</label>
<input type="text" id="ssn" name="ssn" placeholder="Enter your SSN" />
<small></small>
</div>
<button type="submit">Submit</button><br><br>
</form>
your code is good. But you are facing this problem because the server is not sending any data after submit.
First, there should be something to handle GET:
var express = require('express');
var app = express();
app.get('/', (req, res)=>{
res.sendFile('index.html');
console.log('Someone saw your website!');
})
app.listen(80);
Secondly, return something after submit:
app.post('/data/name/:name/ssn/:ssn', function(req, res) {
console.log('req.query: ', req.query); // {}
console.log('req.query.name: ',req.query.name); // undefined
console.log('req.query.ssn: ',req.query.ssn); // undefined
console.log('req.params: ',req.params); // { name: ':name', ssn: ':ssn' }
console.log('req.params.name: ',req.params.name); // :name
console.log('req.params.ssn: ',req.params.ssn); // :ssn
res.end('Thankyou, \n Your Name:'+req.params.name+'\n Your Ssn:'+req.params.ssn);
});

Form in html nodejs returns undefined after receiving post request

I did in HTML a <form></form> object which should return a username, a email and a password, but for some reason it returns undefined if I do req.body.name or anything else and it just won't work and idk why
This is my HTML markup:
<div style="margin: auto; width: 400px; text-align: center; margin-top: 50px;" class="card">
<h1 class="loginTitle card-title" style="margin-top: 10px;">Register</h1>
<div class="card-body">
<form action="/register" method="POST">
<div>
<label class="loginLabel" for="name">Username: </label>
<input style="margin-left: 68px;" class="loginInput" id="name" name="name" required type="text">
</div>
<div>
<label class="loginLabel" for="email">Email: </label>
<input style="margin-left: 110px;" class="loginInput" id="email" name="email" required type="email">
</div>
<div>
<label class="loginLabel" for="password">Password: </label>
<input style="margin-left: 76px;" class="loginInput" id="password" name="password" required type="password">
</div>
<button type="submit" style="margin-top: 10px;">Register</button>
</form>
Login
</div>
</div>
And this is my NodeJS code:
website.post('/register', async (req, res) => {
var usersReg = []
try {
const hashedPw = await bcrypt.hash(req.body.password, 10)
usersReg.push({
name: req.body.name,
email: req.body.email,
password: hashedPw
})
res.redirect('/login')
}
catch {
res.redirect('/register')
}
console.log(usersReg)
})
Please help me - I don't understand where the error is coming from.
(If I don't do catch it says just that the bcrypt.hash() method needs a string)
This is happening because you are not probably using body-parser. You should use the middleware in your server entry point to parse the body of the requests.
Also, your question is duplicated and you can find the complete answer here.
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())

nodejs getting another page

I have a small problem about nodejs and html. There is an error somewhere that I couldn't see. I have been getting this error for 2 days. (cannot get /aP.html)
There is nothing wrong about sql connection, and first and second pages. But when I want to go aP.html from secondpage I keep getting this error.
My nodejs code:
var mysql = require('mysql');
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var connection = mysql.createConnection({
......
});
connection.connect((err) => {
if(err){
throw err;}
else console.log("connected");
});
var app = express();
app.use(bodyParser.urlencoded({extended : true})); //forma girilen datanın parse edilebilmesi için
//başka directorylerdeki klasörleri kullanacaksan
app.use('/js', express.static(__dirname + '.....'));
//gidilecek sayfa
app.get('/', function(request, response) {
res.render('/aP.html', {});;
});
console.log("got it");
app.post('/aP.html', function(request, response) {
var p_name = request.body.urun_adi;
var code = request.body.barkod;
var quantity = request.body.stok_sayi;
var price = request.body.satis_fiyati;
var cost = request.body.maliyet;
var supplier = request.body.firma_adi;
// var username = request.body.id;
/* foreign key olan user id burada kullanılacak mı?*/
console.log(p_name);
connection.query( "INSERT INTO `stok` (`urun_adi`, `barkod`, `stok_sayi`, `satis_fiyati`, `maliyet`, `firma_adi`) VALUES ('"+p_name +"','"+ code +"','"+ quantity +"','"+ price +"','"+ cost +"','"+ supplier+"')");
if(err) throw err;
response.send('save succesful');
});
app.listen(3000);
My HTML code(just for trying):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form action="/aP.html" method="post" class= "col s12">
<input type="hidden" name="e_id" value="">
<div class="form-group row">
<label for="p_name" class="col-2 col-form-label"> Adı</label>
<div class="col10">
<input type="text" name="p_name" value="" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="code" class="col-2 col-form-label"> Barkod</label>
<div class="col10">
<input type="text" name="code" value="" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="quantity" class="col-2 col-form-label"> Adet</label>
<div class="col10">
<input type="text" name="quantity" value="" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="price" class="col-2 col-form-label"> Fiyat</label>
<div class="col10">
<input type="text" name="price" value="" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="cost" class="col-2 col-form-label"> Maliyet</label>
<div class="col10">
<input type="text" name="cost" value="" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="supplier" class="col-2 col-form-label"> Tedarikçi</label>
<div class="col10">
<input type="text" name="supplier" value="" class="form-control">
<input type="submit" name="submit" value="Save Stock">
</div>
</div>
</form>
</body>
</html>
What view engine are you using? If it is ejs you will have to require it and change some of your code. Look at my example and maybe it will clear things up for you. If this is your question.
first npm install ejs
Index.js or server.js depending on what you name it. (start file)
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(express.static("public"))
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.set("port", 3001)
app.get('/', function (req, res) {
res.render('index')
});
app.use('*', function (req, res) {
res.status(400);
res.json({
'error': 'Deze URL is niet beschikbaar.'
});
});
app.listen(process.env.PORT || 3001, function() {
console.log('De server luistert op port ' + app.get('port'));
});
module.exports = app;
Then create a views directory in the root of the project. (same level as the index.js) It is important that you name it that.
In the views folder create a file (in your case aP) with .ejs extension. No HTML extension, because you will use the ejs view engine. It will automatically search in de views directory for the ejs files. Put the html code from aP.html into the newly created aP.ejs file.
I hope this is the answer you are looking for if there are any other problems or you want to do it differently, please let me know.
Edit: different way without ejs
Change this line:
app.get('/', function(request, response) {
res.render('/aP.html', {});;
});
Into this:
app.get('/', function(request, response) {
response.sendFile(path.join(__dirname+'/aP.html'));;
});
Make sure the aP.html is on the same level as the index.js file.
Your problem was (I think) that is didn't recognize res because you name it response. Furthermore you should use sendFile and it will work. I hope this helped.

Inserting form data into MySQL database when using NodeJS Express

For a school project I need to insert data from a html form into my database. The problem is, I never worked with NodeJS, Express, Handlebars or JavaScript before and I cant seem to figure out how it works, I currently have this form in my .hbs file
<div class="row">
<form action="" method="post" class="col s12">
<div class="row">
<div class="col s3 offset-s1">
<label>Sensor Type</label><br>
<label>
<input id="combo" class="with-gap" name="sensorType" type="radio"/>
<span>Temperature & Humidity</span>
</label><br>
<label>
<input id="temp" class="with-gap" name="sensorType" type="radio"/>
<span>Temperature</span>
</label><br>
<label>
<input id="humid" class="with-gap" name="sensorType" type="radio"/>
<span>Humidity</span>
</label>
</div>
</div>
<div class="row">
<div class="input-field col s3 offset-s1">
<select id="sensorForest">
<option value="" disabled selected>Choose your forest</option>
<optgroup label="The Netherlands">
<option value="streekbos">Streekbos Bovenkarspel</option>
</optgroup>
<optgroup label="United States of America">
<option value="losAngeles">Los Angeles National Forest</option>
</optgroup>
</select>
<label>Forest</label>
</div>
<div class="input-field col s3">
<textarea id="textarea2" class="materialize-textarea" data-length="50"></textarea>
<label for="textarea2">Enter sensor Location</label>
</div>
</div>
<div class="row">
<div class="input-field col s6 offset-s1">
<div class="input-field col s6">
<input id="latitude" type="text" class="validate">
<label for="latitude">Latitude</label>
</div>
<div class="input-field col s6">
<input id="longitude" type="text" class="validate">
<label for="longitude">Longitude</label>
</div>
</div>
</div>
<div>
<div class="row">
<div class="col s12 offset-s1">
<button class="btn waves-effect waves-light" id="submit">Submit
<i class="material-icons right">send</i>
</button>
</div>
</div>
</div>
</form>
</div>
Ive also managed to extract the values of the fields in the form using the following script, but I dont think I can use this since I have to use NodeJS
<script>
var submit = document.getElementById("submit");
submit.onclick = function () {
//var sensorType = document.getElementById("sensorType").value;
var sensorForest = document.getElementById("sensorForest").value;
var sensorLocation = document.getElementById("textarea2").value;
var latitude = document.getElementById("latitude").value;
var longitude = document.getElementById("longitude").value;
console.log(sensorForest, sensorLocation, latitude, longitude);
};
</script>
Does anyone know how I'm supposed to send the data to my database or know a good tutorial that explains me how to do it?
Thank you
To connect your NodeJS/ExpressJS application to a database (mongodb, mysql,...) you need an ORM library. For your case i suggest Sequelize. All infos at http://docs.sequelizejs.com/
no you don't need an ORM library. You can just use mysql package from npm
Well before you save anything to a database, you have to get it to your server. I recommend using built-in fetch or if you want better browser support use axios, request-promise or superagent. All of these packages can be found on npm
Client
Underneath your click handler
fetch('http://localhost:3000/sensors', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
sensorForest,
sensorLocation,
latitude,
longitude,
})
})
.then(function (results) {
return results.json()
})
.then(function (results) {
console.log('got results', results)
})
.catch(function (ex) {
console.error(ex)
})
Dependencies
npm init -y && npm i --save express body-parser
Server
const express = require('express')
const { json } = require('body-parser')
const app = express()
const PORT = process.env.PORT || 3000
app.post('/sensors', json(), (req, res, next) => {
const body = req.body
// ...save `body` to database
// use mysql, sequelize, or knex
res.send(body)
})
app.listen(PORT, () => console.info(`Server listening on port "${PORT}"`))

How to handle post request when user hits submit on very basic node.js/html login page

I have created a login page using some HTML/CSS and I want the user to enter a pre-determined password, if the password is correct, they can enter the site, if not, they can't. I have looked up a lot of tutorials/sites etc. but they either use Mongodb to create unique passwords or else use Passport which is not what I'm looking for. I realise having a pre-determined password is not best practice but it suits for the scope of what I'm doing. I plan to change it once I get a basic set up going.
There is a fully functioning site when the user logs in, I just have very little experience with Node.js and not really sure how to handle the post request
This is my the form part of my HTML page (login.ejs)
<form method="post">
<div class="form-group">
<label>Password</label>
<input type="text" class="form-control" name="name" id="name">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
And this is my part of my server.js file
var express = require('express');
var config = require('./config');
var bodyParser = require('body-parser');
var mandrill = require('mandrill-api/mandrill');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static('dist'));
app.use(bodyParser.urlencoded({ extended: false }));
//other stuff
app.post('/login', function (req, res) {
//user enters predetermined password
//user hits the submit button
//if password = "login"
//go to home page
//if password != "login"
//go to error page
});
First, you need to specific the action attribute of the form to be the node route you want to send to. Your form will simply change to:
<form method="post" action="/login">
<div class="form-group">
<label>Password</label>
<input type="text" class="form-control" name="name" id="name">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
In your node file, since you are using body-parser it is very simple to access the body of the POST request.
app.post('/login', (req, res) => {
var data = req.body.name;
});
Where name is the value of the name attribute on the input tag in your form.
modify client side code as
<form method="post" action="/login">
<div class="form-group">
<label>Password</label>
<input type="text" class="form-control" name="name" id="name">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
and modify server side code as:
app.post('/login', function (req, res) {
if (req.body.name == "login")
res.redirect('/home');
if (req.body.name != "login")
res.redirect('/error');
});
app.get('/home', function(req, res) {
// If you are using ejs, you can render ejs
res.sendFile(__dirname + 'path_to_folder_containing_htmls/home.html');
});
app.get('/error', function(req, res) {
// If you are using ejs, you can render ejs
res.sendFile(__dirname + 'path_to_folder_containing_htmls/error.html');
});