Express - Cannot POST /quotes - node.js

Note I did shuffle through a LOT of answers, couldn't find one that matched mine.
Trying to learn express and node. When submitting the form in index.html, the following returns "Cannot POST /quotes" in browser and nothing in the console, but the GET method works fine and loads the page.
const express = require("express");
const app = express();
app.listen(3000, () => {
console.log("listening to port 3000");
});
app.get('/', (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post('/post', (req, res) => {
console.log("Hellloooooooooo!");
});
index
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="stylesheet.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="script.js" type="text/javascript"></script>
<title></title>
</head>
<body>
<form action="/quotes" method="POST">
<input type="text" placeholder="name" name="name">
<input type="text" placeholder="quote" name="quote">
<button type="submit">SUBMIT</button>
</form>
</body>
</html>

there is no quotes route, you have only 2 routes and only one post /post route but no post /quotes route
const express = require("express");
const app = express();
app.listen(3000, () => {
console.log("listening to port 3000");
});
app.get('/', (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post('/post', (req, res) => {
console.log("Hellloooooooooo!");
});
// just make a simple quotes route
app.post('/quotes', (req, res) => {
console.log("hello from quotes route!");
});

Related

How to upload a file using node js streams and HTML forms?

I want to upload a file using NodeJS streams and HTML forms. I have a simple server.
It is working when I upload the file using Postman. But when I upload through HTML form, the file is uploaded but is not readable. How to do it?
This is index.js:
const app = require('express')();
const fs = require('fs');
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.post('/file-upload', (req, res) => {
const filePath = 'uploads/uploaded-file';
const stream = fs.createWriteStream(filePath);
req.pipe(stream);
stream.on('close', () => {
res.send({ status: 'success', filePath })
});
});
// Start server
app.listen(3000, () => console.log("The server is running at localhost:3000"));
This is index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<h1>File Upload</h1>
<form method="post" action="/file-upload" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="upload">
</form>
</body>
</html>
This is the postman request screenshot:
As you can see you're trying to upload the file through a form using multipart/form-data whereas you're uploading it as binary in postman.
To fix this you can setup up a multipart/form-data parser on your server side (e.g. using multer), which would look something like this:
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
// ...
app.post('/file-upload', upload.single('file'), (req, res) => {
res.send({ status: 'success', filePath: req.file.path })
});

How to populate the data scraped from API in node js into EJS template

My index.js file on root directory
const express = require("express");
const app = express();
const path = require("path");
const axios = require("axios").default;
const cors = require("cors");
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "/views"));
app.use(
cors({
origin: "http://localhost:3000",
})
);
fetchData = async () => {
const data = await axios.get(
"https://nepse-data-api.herokuapp.com/data/todaysprice"
);
console.log(data);
return data;
};
app.get("/", (req, res) => {
const nepseData = fetchData();
res.render("home.ejs", { nepseData });
});
app.listen(3000, () => {
console.log("listening to port 3000");
});
My home.ejs file on views directory
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<%= nepseData %>
</body>
</html>
The browser is displaying this when I run the server
The API is sending this type of data
I want to show the name and prices on my ejs file. What should I do now??
You have to add await there:
app.get("/", async (req, res) => {
const nepseData = await fetchData();
res.render("home.ejs", { nepseData });
});
And then you can iterate over the data:
<% nepseData.forEach(function(row){ %>
<%= row.companyName %> <%= row.minPrice %>
<% }); %>

How do I onclick/addeventlistener to an EJS template?

I'm trying to build a database using mongodb where it will render to an html page using ejs. Backend is node/express.
How do I link the button to an addeventlistener. EJS documentation is limited and I've read other posts that says ejs only renders html but no other functionality.
Eventually, I would like to use an async/await to link the js with the backend.
Here is my ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>The Beautiful Game</h1>
<form action="/players" method="POST">
<input type="text" placeholder="name" name="name" />
<input type="text" placeholder="club" name="club" />
<button type="submit" class='submitButton'>Submit</button>
</form>
<h2>Players</h2>
<ul class="players">
<% for (var i = 0; i < players.length; i++) {%>
<li class="players">
<span><%= players[i].name %></span>:
<span><%= players[i].club %></span>
<button class="dataDeleteNameButton" data-id="<%=players[i]._id%>">Delete</button> <!-- linking this button -->
</li>
<% } %>
</ul>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
Here is my js:
document
.querySelector("dataDeleteNameButton")
.addEventListener("click", deleteEntry);
async function deleteEntry() {
console.log("Button is working!");
}
Here is the server, if needed:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const cors = require("cors");
const MongoClient = require("mongodb").MongoClient;
const PORT = process.env.PORT || 8000;
app.use(cors());
const username = "hidden";
const password = "hidden";
const connectionString = `mongodb+srv://${username}:${password}#cluster0.7k2ww.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
MongoClient.connect(connectionString, { useUnifiedTopology: true })
.then((client) => {
console.log("Connected to database");
const db = client.db("soccer-players");
const playerCollection = db.collection("players");
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", (req, res) => {
db.collection("players")
.find()
.toArray()
.then((result) => {
res.render("index.ejs", { players: result });
})
.catch((error) => console.error(error));
});
app.get("/api/players", (req, res) => {
db.collection("players")
.find()
.toArray((err, arr) => {
res.json(arr);
});
});
app.post("/players", (req, res) => {
playerCollection
.insertOne(req.body)
.then((result) => {
res.redirect("/");
})
.catch((error) => console.error(error));
console.log(req.body);
});
app.delete("/", (req, res) => {
// playerCollection.deleteOne() <--
// let findID =
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
})
.catch((error) => console.error(error));
Picture of what it looks like:
This is my script tag path: ../client-side-folder/js-folder/main.js
Directory:
main-folder
+--client-side-folder
+----js-folder
+------main.js
+--views-folder
+----index.ejs
You can just do onclick="myFunction(theIdOfTheButtonHere)"
Here is an example:
https://www.w3schools.com/jsref/event_onclick.asp

How to use sweetalert in nodejs?

I have a nodejs code given with html code, I want to show a sweet alert on client side,after process a function in nodejs?.
var express = require('express');
var router = express.Router();
const Swal = require('sweetalert2');
router.post('/add', function(req, res, next) {
Swal('Hello world!');
});
<!DOCTYPE html>
<html lang="pt_br">
<head>
</head>
<body>
<h1 class="text-center title-1"> Cad </h1>
<form action="/add" method="post">
<input type="submit" value="Save"/>
</form>
</body>
</html>
Here's the only way you can show a popup swal
var express = require('express');
var router = express.Router();
router.post('/add', function(req, res, next) {
res.json("Hello world!")
});
<!DOCTYPE html>
<html lang="pt_br">
<head>
</head>
<body>
<h1 class="text-center title-1"> Cad </h1>
<form id="form" action="#" method="post">
<input type="submit" value="Save"/>
</form>
</body>
</html>
<script>
//import JQuery from script
//import swal script
$("#form").on("submit", function(e){
e.preventDefault();
$.ajax({
url: "/add",
method: "post"
}).done(d=>{
swal(e.responseJSON);
});
})
</script>
Here you can do using EJS
var express = require('express');
var router = express.Router();
router.post('/add', function(req, res, next) {
res.status(201).render('new', { isAdded : true } );
});
In HTML side
<% if (isAdded) { %>
<script>
Swal.fire(
'Good job!',
'Data saved',
'success'
)
</script>
<% } %>
In order to deal with this, you can use query parameters.
So, Here is what you can do
On the server
var express = require('express');
var router = express.Router();
router.post('/login', (req, res)=>{
res.redirect("/login?success=true&message=Logged In Successfully")
});
On the Client-Side (EJS)
<script>
var urlParams = new URLSearchParams(window.location.search);
if(urlParams.has('success') && urlParams.get('success')){
swal({
title: "Failed",
text: `${message}`,
icon: "error",
button: "Okay",
}).then(()=>{
console.log(window.location.hostname)
window.location.replace(window.location.origin + '/login');
})
}
This will simply popup swal. And you can toggle the value of success to render error and success messages.

Linking HTML button to node.js post

Basic question here: I set up a local server with express and I want to create a file on the server by clicking a HTML button.
Here is the srcServer.js:
var express = require('express');
var path = require('path');
var open = require('open');
var fs = require('fs');
var port = 3000;
var app = express();
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '../src/index.html'));
});
app.post('/', function(request, respond) {
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
});
app.listen(port, function(err){
if(err){
console.log(err);
}else{
open('http://localhost:' + port);
}
});
And this is the index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<h2>The Button Element</h2>
<form action="" method="post">
<button name="foo" value="send">Send</button>
</form>
</body>
</html>
I am pretty sure the problem is how I am handling the HTML button, but I dont know better. The error I receive when I click on it is: Cannot POST /.
The problem was with the folders- I messed up calling them in the srcServer.js. It works fine after I put all the files in one folder, this way it was easier to do it right.

Resources