Express NodeJS: Append text / <p> element to a HTML file in POST - javascript

I am trying to make a basic login system using Express, where if the user's username and password are correct according to a MySQL database, it adds a short "Success!" or "Failure" message to the bottom of the page when it receives a POST request.
I've tried using res.write("<p>Success!</p>") and res.send("<p>Success!</p>"), but neither have worked - instead they just create a new page with "Success!".
HTML:
<html>
<head>
<meta charset="utf-8">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form id="contact-form" method="POST" action="/login">
<label for="Username">Username: </label>
<input name="Username" maxlength="45"><br><br>
<label for="Password">Password: </label>
<input name="Password" type="password" maxlength="45"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
JS:
const port = 3000;
const express = require("express");
const mysql = require("mysql2");
const app = express();
const bodyParser = require("body-parser");
var conn = mysql.createConnection({
host: "localhost",
database: "database",
user: "<Username>",
password: "<Password>"
});
conn.connect((err) => {
if(err) throw err;
console.log("Connected to database.");
})
app.use(express.static(__dirname + "/public"));
app.use(bodyParser.urlencoded({
extended: false
}));
app.get("/login", (req, res) => {
res.sendFile(__dirname + "/Login.html");
});
app.post("/login", (req,res) => {
let form = req.body;
let sqlQuery = "SELECT * FROM logins WHERE Username = '" + form.Username + "' AND Password = '" + form.Password + "';";
conn.query(sqlQuery, (err, result, fields) => {
if(err) throw err;
if(result.length == 1) {
res.write("<p>Success!</p>")
} else {
res.write("<p>Failure.</p>")
}
})
});
app.listen(port);
So, how could I append a short p element / text to the bottom of an HTML file?

Okay,
So when the submit button in the login form is hit, it creates a totally new request and the old page is no longer in the context of request.
So, res.write() creates a new page, since a new request is generated.
If you want to append the failure and success messages on the same page, you can use ajax request instead of default form submission.
Send the ajax request, you will receive the response without a page reload, and then upon receiving the response, using javascript, you can append a new element with message from the server
const contactForm = document.getElementById('contact-form');
contactForm.addEventListener('submit',(e)=>{
e.preventDefault();
const username = contactForm.elements['username'].value;
const password = contactForm.elements['password'].value;
// now make the ajax call, you can use any library like FetchAPI, axios or even jQuery Ajax
fetch('http://backend/endpoint',{
method: 'POST',
body: JSON.stringify({username,password})
})
.then((res)=>{
return res.json();
})
.then((data)=>{
console.log(data)
// you can append new element here
// based on data (success or failure)
})
})

Related

cannot access the POST form data sent by HTML/Javascript code at node js code

I made a simple nodejs server which serves a html page to the user.The page contains a input text box of userID. When the user presses the button submit, I take that userID entered by the user and put it in form Data and send it to my server function (submitForTest) through POST method.
Now, inside my function of nodejs which handles submitForTest, I tried to access the userID , but I was getting res.body as {} , so not able to figure out how to access userID here.
Can anyone please point what I need to get the userID at my node js code.
My HTML file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<label>User ID</label>
<div>
<input type="text" id="userid" >
</div>
</div>
<div>
<div>
<button type="submit" onclick="submitForTest()">Submit</button>
</div>
</div>
<script type="text/javascript">
function submitForTest()
{
var userID = document.getElementById('userid').value;
let formData = new FormData();
formData.append("userID", userID);
//alert("hello");
fetch('http://MY-SERVER:3000/submitForTest', {method: "POST", body: formData});
}
</script>
</body>
</html>
My Node js file :
'use strict'
const fs = require("fs")
const express = require('express')
var path = require('path')
const app = express()
var bodyParser = require('body-parser')
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var jsonParser = bodyParser.json();
app.get('/',function(req,res) {
res.sendFile('small.html');
});
app.post('/submitForTest', function(req, res) {
//want to print userID here .. but the below is coming as {} here ..
console.log(req.body);
})
// Tell our app to listen on port 3000
app.listen(3000, function (err) {
if (err) {
throw err;
}
console.log('Server started on port 3000')
})
Please help.
Regards
The problem is FormData is sending body encoded as multipart/form-data. You'll have to add middleware able to handle multipart body format. Busboy or multer for example.
Example of using multer to upload a file and send userID field:
// --- form
<form action="/submitForTest" enctype="multipart/form-data" method="post">
<input type="file" name="uploaded_file">
<input type="text" name="userID">
<input type="submit" value="Submit">
</form>
// --- server
var multer = require('multer')
var upload = multer({ dest: './uploads/' }) // where the uploaded files will be stored
app.post('/submitForTest', upload.single('uploaded_file'), function (req, res) {
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body)
});
Or to send your data in urlencoded or json format. Something like that for json for example:
function submitForTest()
{
var userID = document.getElementById('userid').value;
fetch('http://MY-SERVER:3000/submitForTest', {
method: "POST",
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({ userID }),
});
}

How do I get the access of user's input and calculate something on my back-end server?

So, I am using Node.js with express to run a server and make a calculator. After that, I downloaded body-parser, to get the access of the numbers the user inputs and use it to calculate the result, but for some reason whenever I try to log one of the numbers on console, just to make sure that it works, it doesn't get logged.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', (req, res) => {
res.sendFile(`${__dirname}/index.html`);
})
app.post('/', (req, res) => {
console.log(req.body);
res.send('Thanks for the information');
})
app.listen(3000, () => console.log('Server Started'));
Your form will look something like this
<form id="post-form" action="/your/post/url" method="POST">
<div class="form-control">
<label for="title">Number</label>
<input type="number" name="number" id="number">
</div>
<button type="submit">
Submit
</button>
</form>
Or in your script tag, you can do something like this.
with this approach, the form gets submitted without reload
// Note: Optional approach (without reloading the page)
// Just above HTML only code also works perfectly fine
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const number= document.getElementById('number')
document.getElementById('post-form').addEventListener('submit', (e) => {
e.preventDefault();
axios
.post('/your/post/url', { number: number.value })
.then((res) => {
//handle response here
})
.catch((err) => { //handle err here});
});
<script>
then in you express app you can do
app.post('/you/post/url/', (req,res,next) => {
// this is how you accces title from you form
// here title will hold value "Value Here"
const { number} = req.body
//calculate here
number = number * number + number
// then send the response
res.send(`calculated number: ${number}`)
});

How to make a post request to mongo db atlas using node.js and express.js

I am trying to make a simple post request to Mongo Db Atlas using Node.js, Express.js and Mongoose.js. I fill out the form and send the request but it just keeps loading, no erros, nothing. ANyone have any ideas?
//Require assets
const express = require('express');
const app = express();
const mongoose = require('mongoose');
let port = 3000;
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const MongoClient = require('mongodb').MongoClient;
const uri = 'mongodb+srv://michael:<PASSWORD-GOES-HERE>#around-town-vsisv.mongodb.net/admin';
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
const collection = client.db('around_town_db').collection('events');
// perform actions on the collection object
client.close();
});
mongoose.Promise = global.Promise;
var eventSchema = mongoose.Schema({
eventName: String,
})
var eventData = mongoose.model('Event', eventSchema);
//Load index page using endpoint
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
//Post using endpoint
app.post('/addevent', (req, res) => {
var userData = {
eventName: req.body.eventName
}
new eventData(userData)
.save()
.then(res => {
res.send('item saved to database');
})
.catch(err => {
res.status(400).send('unable to save to database');
});
});
//Listen on port 3000
app.listen(port, () => {
console.log('Server listening on port ' + port);
});
Below is a simple form for submitting the post request. Any ideas on what I am missing?
<!DOCTYPE html>
<html>
<head>
<title>Add a local event</title>
</head>
<body>
<div class="app">
<h1>Add an event</h1>
<form method="post" action="/addevent">
<label>Enter event Name</label><br>
<input type="text" name="eventName" placeholder="Enter event name..." required>
<input type="submit" value="Add Event">
</form>
</div>
</body>
</html>
OK, so it looks like you have two problems. First, you're not letting Mongoose itself connect to your database, and second you're overwriting the response variable. If you note your .then() callback in the userData.save() promise chain, you're calling that result variable 'res' as well as the response variable 'res' from the route callback.
To fix the first problem, somewhere in your app startup, one time call (instead of your current MongoClient code)
mongoose.connect(uri)
You can also use mongoose.createConnection() if you want more fine-grained control over the connection, or need to make multiple connections to different databases.
Second problem, your post handler should look like this:
//Post using endpoint
app.post('/addevent', (req, res) => {
var userData = {
eventName: req.body.eventName
}
new eventData(userData)
.save()
.then(result => { // note the use of a different variable name
res.send(result); // also, you generally want to send *something* down that lets the user know what was saved. Maybe not the whole object, but this is illustrative and the client will at least need to know something (e.g. the id) to refer to the object by in the future.
})
.catch(err => {
res.status(400).send('unable to save to database');
});
});
Unrelated to your problem, but most folks write Express APIs in a RESTful manner. If you want to follow that convention, then your routes should look more like this:
GET /events // list the events
GET /events/:eventId // get a single event by ID
POST /events // add a new event
PUT /events/:eventId // update an existing event
DELETE /events/:eventId // remove an event
Try something like follow:
app.post('/addevent', (req, res) => {
var userData = new eventData({
eventName: req.body.eventName
})
userData.save()
.then(res => {
res.send('item saved to database');
})
.catch(err => {
res.status(400).send('unable to save to database');
});
});

Do MySQL actions on call - Node.js

I have been learning some Node.js and was trying to make a program where you enter a username and password and it is checked against a MySQL database. I don't know if I'm doing the whole authentication business correctly, but my question is this: Can you call a MySQL function after the start of the code (i.e. on some kind of function call).
Can you do a MySQL action on a function call?
I've looked on the internet and different Stack Overflow questions, but I still don't really understand. I may be missing a trick about what Node.js actually does though.
This is my code:
HTML:
<html>
<head>
<title>Basic User Information</title>
</head>
<body>
<form action="http://localhost:8888/user" method="POST">
Username: <input type="text" name="username"> <br>
Password: <input type="text" name="password"> <br></select>
<input type="submit" value="submit">
</form>
</body>
</html>
Node.js:
//import the express module
var express = require('express');
//import body-parser
var bodyParser = require('body-parser');
//store the express in a variable
var app = express();
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
con.query("CREATE DATABASE authtest", function (err, result) {
if (err) throw err;
console.log("Database created");
});
con.query("CREATE TABLE users (username VARCHAR(255), password VARCHAR(255))", function (err, result) {
if (err) throw err;
console.log("Table created");
});
});
//configure body-parser for express
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
//allow express to access our html (index.html) file
app.get('/index.html', function(req, res) {
res.sendFile(__dirname + "/" + "index.html");
});
//route the GET request to the specified path, "/user".
//This sends the user information to the path
app.post('/user', function(req, res){
response = {
username : req.body.username,
password : req.body.password
};
//this line is optional and will print the response on the command prompt
//It's useful so that we know what information is being transferred
//using the server
console.log(response);
//convert the response in JSON format
res.end(JSON.stringify(response));
con.connect(function(err) {
if (err) throw err;
var sql = "INSERT INTO users (username, password) VALUES (response.username, response.password)";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted");
});
});
});
//This piece of code creates the server
//and listens to the request at port 8888
//we are also generating a message once the
//server is created
var server = app.listen(8888, function(){
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});
Edit:
Would I need to do this in another script? So, there is one for the initialisation of the page and one for inserting the data into the MySQL database?
as far i can see in your code you are setting a INSERT in the users table with the data passed by the form, and setting the server to respond before the action is complete so the page recieve the awnser anyway, but awnsering your question, YES, the actions you put in the "index.js" of your node server run as soon as it starts.

Twilio JavaScript - SMS from client to server

I've found docs teaching on how to implement Twilio on server-side using Node, however, I couldn't find an end-end example where I can send a SMS coming from my client app.
Can anyone tell me what the implementation would look like to send a post custom SMS from client to server?
Disclaimer my server file is named as app.js and my client file is named as index.js
**1- This is what I have currently setup on my app.js
const express = require('express');
const app = express();
const path = require('path');
const twilio = require('twilio');
const bodyParser = require('body-parser');
//JSON DATA
const guests= require('./public/data/Guests');
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static('public'));
//SET PORT
app.set("port", process.env.PORT || 3000);
//GET JSON DATA
app.get('/data', function(req, res) {
Promise.all([guests])//combine requests into one object
.then(([guests]) => {
res.send({guests});
});
});
//CATCHALL
app.get("/*", function(req,res){
let file = req.params[0] || "/views/index.html";
res.sendFile(path.join(__dirname, "/public/", file));
});
//LISTEN ON PORT
app.listen(app.get("port"), function(){
console.log("Listening on port: " , app.get("port"));
});
let client = new twilio('xxxxxxxxxx', 'xxxxxxxxxxxxx');
app.post('/sms', (request, result) => {
const message = request.body.message;
client.messages.create({
to: +1847820802492359,
from: +8475302725792530 ,
body: message
}).then(() => {
// message sent successfully, redirect to the home page.
res.redirect('/');
}).catch((err) => {
console.error(err);
res.sendStatus(400);
});
});
-2 am trying to process a dynamic message in my index.js. The code works on the DOM properly, it is just the SMS with Twilio that isn't posting the message to the server
$(function() {
$.ajax({
type: "GET",
url: "/data",
success: res => {
//console.log(res);
handleMessage(res);
},
error: err => console.log(err)
});
//message method
let handleMessage = (res) => {
const getFirstName = res.guests.map(name => name.firstName);
//populate drop-down select
let handleSelect = () => {
//adds first names to select dropDown
$.each(getFirstName, function(i, value) {
$('#selectName').append($('<option>').text(value).attr('value', value));
});
};
handleSelect();
let handleSubmit = () => {
$("#form").submit(function(e) {
e.preventDefault();
let name = $('#selectName').val();
let greetGuest = `Welcome ${name}!`;
console.log(greetGuest);
//append to Dom
$('.showMessage').append(`<div class="newMessage"><span>${greetGuest}</span></div>`);
});
};
handleSubmit()
};
});
-3 HTML form
<form id="form" action="/sms" method="POST">
<label>
<label for=selectName>Guest
<select id="selectName" class="select " name="sms">
</select>
</label>
</label>
<input type="submit" value="send" class="btn btn-success" />
</form>
Am I having an asynchronicity issue here?
Twilio developer evangelist here.
I can give you a basic example here, which should give you a good idea of how to achieve this. I'll start with the server side, which you already have the basics of.
Firstly, I would recommend you use a POST request rather than a GET, simply because GETs can be easily repeated by users or cached by proxies. I assume you are using Express as the web application server. You will also need the body-parser module to read the data that we send from the client side.
const Twilio = require('twilio');
const express = require('express');
const bodyParser = require('body-parser');
const app = new express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static('public'));
const twilio = new Twilio(YOUR_ACCOUNT_SID, YOUR_AUTH_TOKEN);
app.post('/messages', (request, result) => {
const message = request.body.message;
twilio.messages.create({
to: TO_NUMBER,
from: FROM_NUMBER,
body: message
}).then(() => {
// message sent successfully, redirect to the home page.
res.redirect('/');
}).catch((err) => {
console.error(err);
res.sendStatus(400);
});
});
app.listen(3000);
This sets up a server which is serving static files from a public directory and then has one endpoint, POST to /messages, that sends a message.
We now need to create the client side. I shall do this in HTML only for simplicity. You need a form that will POST to the /messages endpoint with, in this case, a single field for the message. I've included a textarea to write the message in and a button to submit the form. If you save this as index.html in the public directory where you run the application from then it should work.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Send a message!</title>
</head>
<body>
<h1>Send a message!</h1>
<form action="/messages" method="POST">
<label for="message">What would you like to send?</label>
<textarea name="message" id="message"></textarea>
<button type="submit">Send!</button>
</form>
</body>
</html>
Let me know if that helps at all.
Update
So you're looking to make the request to the server using Ajax so your page doesn't reload and you can display a different message. Your current form seems to have removed the message textarea that I added, I'll put it back in again. I assume you also want to send the message to whichever guest you are welcoming at the time, but I don't know how that works in your system, so I'm going to avoid that for now and hopefully you can sort it out.
So, if you update your form to something like this:
<form id="form" action="/sms" method="POST">
<label>
<label for=selectName>Guest
<select id="selectName" class="select " name="sms">
</select>
</label>
</label>
<label for="message">Message</label>
<textarea id="message" name="message"></textarea>
<input type="submit" value="send" class="btn btn-success" />
</form>
Then you need to add to your JavaScript a way to actually submit the form (since you are preventing the submission with e.preventDefault().
const $form = $('#form');
$form.submit(function(e) {
e.preventDefault();
let name = $('#selectName').val();
let greetGuest = `Welcome ${name}!`;
console.log(greetGuest);
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serialize(),
success: function(data) {
console.log("The message has been sent");
},
error: function() {
console.error("The message couldn't be sent");
console.error(...arguments);
}
})
//append to Dom
$('.showMessage').append(
`<div class="newMessage"><span>${greetGuest}</span></div>`
);
});
In this case we are hooking into the callback for the submit event to make a new $.ajax request to the form's action, using the method (POST), and including the form data (which we get from $form.serialize()). We then setup success and error callbacks as you've done at the top of the function.
Let me know if this helps.

Categories

Resources