I want to submit a form and then return an object from my MongoDB database without reloading the page. Therefore when I submit my form I use an event handler that prevents the default behavior of the form to reload the page. The problem is this is interfering with my server side script and causing req.body
to return null. If I remove e.preventDefault()
from my client side script then req.body
works fine but the page refreshes and just displays a json from my database. How would I get around this?
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>Message in a Bottle</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div id = "icon">
<img id = "iconImg" style = "width:100%"src = "icon.svg"/>
</div>
<div id = "form">
<form method="post" action="/">
<input type="text" name="sender"/>
<textarea rows="20" cols="50" name="message"></textarea>
<button type = "submit" onclick="onClick(event)">submit</button>
</form>
</div>
<div id = "message">
<p id = "senderName"></p>
<p id = "response"></p>
<button onclick="closeMessage()">New Message</button>
</div>
</body>
<script type = "text/javascript" src = "packageHandler.js"></script>
</html>
Here is my client side script:
const form = document.getElementById("form");
const icon = document.getElementById("icon");
const message = document.getElementById("message");
function onClick(e){
e.preventDefault();
console.log("loading results");
form.style.opacity = "0%";
form.style.pointerEvents = "none";
icon.style.width = "80%";
fetch('http://localhost:3000/', {method: 'POST'})
.then((response) => {
icon.style.width = "33%";
message.style.opacity = "100%";
message.style.pointerEvents = "auto";
return response.json();
})
.then((data) => {
document.getElementById("senderName").innerHTML = data.name;
document.getElementById("response").innerHTML = data.message;
});
//await results
//fade in <div id = "message">
//display results in <div id = "message">
}
function closeMessage(){
console.log("message closed")
form.style.opacity = "100%";
form.style.pointerEvents = "auto";
message.style.opacity = "0%";
message.style.pointerEvents = "none";
//fade out <div id = "message">
//fade in <div id = "form"
}
Here is my server side script:
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
require('dotenv/config');
const app = express();
const fs = require('fs');
const port = 3000;
app.use(express.urlencoded());
app.use(express.static('public'));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
//Routes
app.get('/', (req, res) => {
fs.readFile('./views/home.html', function (err, data) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data);
res.end();
});
});
app.post('/', (req, res) => {
MongoClient.connect(process.env.DB_CONNECTION, { useUnifiedTopology: true, useNewUrlParser: true }, function (err, db) {
if (err) throw err;
const dbo = db.db("mydb");
const messageTable = dbo.collection("messages");
let myobj =
[{
name: req.body.sender,
message: req.body.message
}];
console.log(myobj)
messageTable.insertMany(myobj, function (err, res) {
if (err) throw err;
console.log("1 document inserted");
});
var myPromise = () => {
return new Promise((resolve, reject) => {
messageTable.aggregate(
[{ $sample: { size: 1 } }]
).toArray((err, data) => {
err
? reject(err)
: resolve(data[0]);
});
});
}
//Step 2: async promise handler
var callMyPromise = async () => {
var result = await (myPromise());
//anything here is executed after result is resolved
return result;
};
//Step 3: make the call
callMyPromise().then(function (result) {
db.close();
res.json(result)
});
});
}); //end mongo client