Form is not submitting in node - javascript

I am trying to make a post request from a html form and cant figure out where im going wrong.
> <form action="/api" method="POST">
<label for="username">username or email address</label>
<input name="username" id="username" type="text">
<label for="password">password</label>
<input id="password"name="password" type="text">
<button >Log in</button>
</form>
here is my main javascript file for the html (not the server)
"use strict"
let options = {
headers:{
"Content-Type" : "application/json"
},
method: "POST",
}
// fetch("/api",options)
And here is my node js server
"use strict"
//Installing express
let express = require(`express`)
let app = express()
app.use(express.json())
//running the server
app.listen(3000,()=>{
console.log("server is running boi");
})
//Middleware to load the static content
app.use(express.static(`public`))
//Database stuff
let Datastore = require('nedb')
let db = new Datastore({ filename: 'database.db' });
db.loadDatabase()
db.insert({username:"sid", password:"westham"})
//Handler for any post requests made
app.post(`/api`,(req,res)=>{
console.log("request was made");
console.log(req.body);
})

Two Observations
No middleware found in your server.js file for handling form data,
use body-parser http://expressjs.com/en/resources/middleware/body-parser.html
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true });
In your html form, if you're not submitting form with JavaScript then mentiod button type as submit
<button type="submit" >Log in</button>

Related

req.files keeps returning undefined

req.files keeps returning undefined. I've tried connect-multiparty, body-parser, and express-fileupload. How do I make it work using express-fileupload and not multer?
here's my frontend:
<form action="/api/upload" method="post">
<label for="imgHere">file:</label>
<input type="file" id="imgHere" name="imgHere"><br><br>
<input type="submit">
</form>
I've checked using inspect element network tab, its sending the image just fine.
here's my backend:
const express = require("express");
const app = express();
const fileUpload = require("express-fileupload")
app.use(fileUpload())
app.post('/api/upload', function(req, res) {
console.log(req.files) // logs undefined
res.send("uploaded.")
});
app.listen(80, function()
{
console.log("Server loaded.")
});
How do I fix this?
You need to specify proper enctype as form attribute as well, like this:
<form action="/api/upload" method="post" enctype="multipart/form-data">
<label for="imgHere">file:</label>
<input type="file" id="imgHere" name="imgHere"><br><br>
<input type="submit">
</form>

Getting string value of required input (html) on cheerio

I'm trying to do a notify function in my website. The button his on HTML (client side) and on press calls a node js function to execute a python script that sends an e-mail to myself (tested and working).
This is my code on the client side (index.html)
<body>
...
<div class="form-popup" id="myForm">
<form class="form-container" name="form-owner">
<h1>Notify Owner</h1>
<label><b>Name</b></label>
<input id="name" style="width:90%" type="text" placeholder="Enter your name" required>
<label><b>Message</b></label>
<input id="context" style="width:90%" type="text" placeholder="Enter Reason" required>
<button type="submit" class="btn" onclick="notifyOwner()">Submit</button>
<button type="button" class="btn cancel" onclick="closeForm()">Close</button>
</form>
</div>
</div>
...
The code on the server side (app.js)
const express = require('express');
const child_process = require('child_process')
const app = express()
const cheerio = require('cheerio');
const port = 80
'use strict';
var request = require('request');
...
app.post("/api/notify", async (req, res) => {
try{
const $ = cheerio.load('<input id="name" style="width:90%" type="text" placeholder="Enter your name" required>');
var subject = $('[id=name]').text();
var body = "ok";
child_process.execSync('python3 sendEmail.py ' + subject + " " + body);
}catch(error){
console.error(error);
}
});
The varialbe 'subject' turns out as null and the script is not runned because that argument is missing
I believe there's some confusion here. Cheerio is used to parse and manipulate HTML strings, but that's not what your front end code is sending. The string you're telling Cheerio to manipulate has no relationship to the request form payload in any way, nor is it a necessary tool for processing the POST request.
You appear to be using JS to submit JSON or form data to the server (as opposed to an HTML form action). req.body and req.query would contain this parsed payload respectively, depending on how your server is set up.
Here's an example of how you can set this up using JSON. Note that I've promisified the exec function to avoid blocking the event loop with a synchronous subprocess call.
Also, the form name and context don't seem to correspond well with subject and body--I assume you'll make this consistent.
You'll want to escape and properly quote your subprocess argument string as well.
public/index.html:
<!DOCTYPE html>
<html lang="en">
<head><title>Test</title></head>
<body>
<form>
<h1>Notify Owner</h1>
<label>
<b>Name</b>
<input id="name" placeholder="Enter your name" required>
</label>
<label>
<b>Message</b>
<input id="context" placeholder="Enter Reason" required>
</label>
<button type="submit">Submit</button>
</form>
<script>
document.querySelector("form").addEventListener("submit", event => {
event.preventDefault();
const name = event.target.querySelector("#name").value;
const message = event.target.querySelector("#context").value;
fetch("/api/notify", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({name, message})
})
.then(res => {
if (!res.ok) {
throw Error(res.statusText);
}
return res.json();
})
.then(data => {
console.log(data);
event.target.reset();
})
.catch(err => console.error(err));
});
</script>
</body>
</html>
server.js:
const {promisify} = require("util");
const exec = promisify(require("child_process").exec);
const express = require("express");
const app = express();
app.use(express.json());
app.use(express.static("public"));
app.post("/api/notify", async (req, res) => {
const {name, message} = req.body; // TODO validate
// do stuff with name and message
console.log(name, message);
try {
//await exec(`python3 sendEmail.py ${subject} ${body}`);
res.json({message: "email sent"});
}
catch (err) {
res.json({error: "failed to send email"});
}
});
app.listen(8000, () => console.log("listening on port 8000"));

POST method not inserting into users array

Im trying to figure out why my post Method won't insert the user made in the register form into my user array, and no array is logged in node. When the register button is clicked, the site is also not redirecting to the /login page. Im not looking for the exact solution maybe just a tip to help me on the right path.
(all libraries is required)
The POST method im using
const express = require('express')
const app = express()
const bcrypt = require('bcrypt');
// helps finding specifik path
const path = require('path')
const port = 3000
// users array
const users = [];
app.use(express.static('views'))
app.listen(port,()=>{
console.log("App is listening on port 3000")
});
// VIGTIGT: tilader at vi kan hente data fra forms via "Name" tagget i formen!
app.use(express.urlencoded({ extended: false }))
// req router fra .auth/user_auth
// Routing: We are mapping to a special respond, and responds a HTML filer
app.get('/contact',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/contact.html'))
})
app.get('/login',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/login.html'))
})
app.get('/register',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/register.html'))
})
app.get('/home',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/home.html'))
})
app.get('/portfolio',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/portfolio.html'))
})
app.get('/adminpage', (req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/adminpage.html'))
})
// post metoder fra form
app.post('/register', async (req, res)=>{
try{
const hashedPassword = await bcrypt.hash(req.body.password, 10)
users.push({
id: Date.now().toString(),
name: req.body.username,
email: req.body.email,
password: hashedPassword
})
res.redirect('/login')
} catch{
res.redirect('/register')
}
console.log(users)
})
form im using
<form>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="username"><b>Username</b></label>
<input type="text" placeholder="Enter username" name="username" required>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" required>
<hr>
<p>By creating an account you agree to our Terms & Privacy.</p>
<button href="/login" type="submit" class="registerbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? Sign in.</p>
</div>
</form>
Firstly, you need to specify a method and an action to determine where the data is being sent to:
<form action="/register" method="POST">
</form>
Secondly, you are not parsing the incoming data when it is received by your server. The req.bodysyntax implies that the data is received as an object/JSON, but I don't see anything in your code that indicates you are doing this.
You can use one of a number of packages to do this for you, and Express has built-in middleware for this purpose. I'd recommend the body-parser package.
const bodyParser = require('body-parser');
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true }))
Worth adding a temporary console.log(req.body) to your function too just to check form data is being received as intended.

NodeJS - socket.on doesn't appear to be called

I am using the Node.JS POST method to submit a form to my server. It is transmitted to the server fine; no problems occur at this stage. However, when I use io.emit with socket.io to transfer the data back to the client, nothing seems to happen client-side. Nothing is printed to the console and I'm getting no errors there or in Command Prompt (where I'm running the server from).
index.html:
<form id="schoolCreateForm" action="http://localhost:3000/createSchool" method="POST">
School name: <input name="schoolName" type="text"><br><br>
Private?: <input name="schoolPrivate" type="checkbox"><br><br>
Entry password: <input name="entryPassword" type="password"><br><br>
<button type="submit">Submit</button>
</form>
<script>
var socket = io();
socket.on('updateSchool', function(response) {
console.log(response);
document.getElementById("headerSchoolName").innerHTML = data.schoolName;
});
</script>
app.js:
var express = require('express');
var app = express();
var serv = require('http').Server(app);
var io = require('socket.io')(serv);
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.post('/createSchool', function(req, res) {
response = {
school_name: req.body.schoolName,
school_private: req.body.schoolPrivate,
entry_password: req.body.entryPassword
};
console.log(response);
res.sendFile(__dirname + '/client/index.html');
io.emit('updateSchool', response);
});
serv.listen(3000);
console.log("Server started on localhost://3000");
Does anyone know what's going on?
<form action="http://localhost:3000/createSchool" method="POST">
School name: <input name="schoolName" type="text"><br><br>
Private?: <input name="schoolPrivate" type="checkbox"><br><br>
Entry password: <input name="entryPassword" type="password"><br><br>
<button type="submit" id="schoolCreateForm">Submit</button>
After submitting your form data it will reload your page, it means socket connection will be ended. If you want to see a response with socket make ajax.post request without reloading the page.
<form id="schoolCreateForm">
School name: <input name="schoolName" type="text"><br><br>
Private?: <input name="schoolPrivate" type="checkbox"><br><br>
Entry password: <input name="entryPassword" type="password"><br><br>
<button type="submit">Submit</button>
</form>
<script>
document.querySelector('#schoolCreateForm').addEventListener('click',
function(e) {
e.proventDefault() // this line will not all to reload page after
/// submitting the
//form data
### writh you ajax request functionality here
})
var socket = io();
socket.on('updateSchool', function(response) {
console.log(response);
document.getElementById("headerSchoolName").innerHTML = data.schoolName;
});

req.files is empty when trying to upload a file to server with node js

HTML:
<form action="/uploadpic" method="post" enctype="multipart/form-data">
<input type="file" data-clear-btn="true" name="image" id="new_pic" value="" placeholder="Choose File">
<input type="submit" value="Add" style="width:30%">
</form>
NodeJS:
app.post('/uploadpic', function(req,res) {
console.log(req.files);
console.log(req.body);});
I also use:
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded());
app.use(bodyParser.json())
app.use(express.bodyParser({uploadDir:'./uploads'}));
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
in the console I get:
{}
{}
i dont seem to understand what could be the problem here.. thanks !
var fs = require('fs');
app.post('/uploadpic', function(req,res) {
//req.files contains array of files iterate and get it
//if it has only one. it is like object
//here is the code for object
if (req && req.files) {
var contentType = req.files.file.type;
var fname = req.files.file.name;
var image_path = req.files.file.path;
fs.readFile(image_path, function (err, data) {
var data = data; //this is your data use this
})
}
})
BodyParser doesn't include file uploads. You need to use something like multer or multiparty.
Also express (4.0+) doesn't come bundled with middleware anymore, so you'll need to use bodyparser for POST requests.

Categories