Been using mongoDB with the mongoose ODM and I can't seem to figure it out. I've been following a tutorial online, but when I test out my code, it gets redirected to an empty page that says "Cannot POST /"
Here is my code:
server.js
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var PORT = 3332;
app.use("/", express.static(__dirname));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost/gamedata", {
useNewUrlParser: true
});
var gameSchema = new mongoose.Schema({
nickname: String
});
var User = mongoose.model("User", gameSchema);
app.post("/addname", (req, res) =>{
var playerNickname = new User(req.body);
playerNickname.save()
.then(item => {
console.log("nickname created")
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
console.log("error baby!");
});
});
app.listen(PORT, function () {
console.log("server is up and running using port " + PORT)
});
index.html
<html>
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap" rel="stylesheet">
<body>
<h1 class="center-align">Create Nickname</h1>
<form method="post" name="/addname">
<input id="pickName" type='text' name='pickName' placeholder='Nickname' required>
<input id='ready' value=" Ready >" type='submit'>
</form>
</body>
<script>
</script>
</html>
What seems to fix it is when i change
app.use("/", express.static(__dirname));
to the following code:
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
But in my specific case i cannot do this.
Does anyone know of a work around?
You should change your index.html
Insteady of use:
<form method="post" name="/addname">
you should use:
<form method="post" action="/addname">
This should solve your problem.
The Action Attribute
The action attribute defines the action to be performed when the form is submitted.
Usually, the form data is sent to a page on the server when the user clicks on the submit button.
In the example above, the form data is sent to a page on the server called "/addname". This page contains a script that handles the form data:
If the action attribute is omitted, the action is set to the current page.
The attribute "name" is used in input fields, not in the tag.
I just found some information here.
https://www.w3schools.com/html/html_forms.asp
Related
First, Sorry if I got the title wrong, I am new and dunno how to start and the terms,
what I want to do is
<form action="/" method="POST">
<select name="cash" id="first">
<option value="AED">AED</option>...
get the value of 'cash' i.e AED
app.post("/", function(.............) {
request(..............)
var cash = req.body.cash;
console.log(cash);
var data = JSON.parse(body);
var price = data.rates.cash;
console.log(price);
res.send( price);}
make a post request and make api call select the price(AED) and res.send and "How to retrieve POST query parameters?" this didn't help me.
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
const request = require('request');
app.use(express.json());
app.use(bodyParser.urlencoded({
extended: true
}));
You can do something like this.
<form method="post" action="http://127.0.0.1:8080/">
<select name="cash" id="first">
<option value="AED">AED</option>
<input type="submit" value="Submit">
</form>
Enter full URL like
<form action="http://127.0.0.1:8080/" method="post">
Node js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
//Note that in version 4 of express, express.bodyParser() was
//deprecated in favor of a separate 'body-parser' module.
app.use(bodyParser.urlencoded({ extended: true }));
//app.use(express.bodyParser());
// access your body data here
app.post('/', function(req, res) {
res.send('You sent the code "' + req.body.cash + '".');
});
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
As I understand correctly you want to:
POST form data to backend
during data processing, request 3rd party API for a price
return a price to the user
The form view index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/" method="POST">
<select name="cash" id="first">
<option value="AED">AED</option>
<option value="USD">USD</option>
</select>
<button id="submit" type="submit">Submit</button>
</form>
<% if (cash && price) { %>
<p>The price for <%= cash %> is <%= price %>.</p>
<% } %>
</body>
</html>
I'm using EJS to conditionally display the price below the <form>.
Here is Express backend:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// I advise you to use axios instead of request for convenience
const axios = require('axios');
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.get('/', function (req, res) {
if (req.query.cash && req.query.price) {
res.render('index', { cash: req.query.cash, price: req.query.price });
}
res.render('index', { cash: null, price: null });
});
app.post('/', async function (req, res) {
const cash = req.body.cash;
try {
const response = await axios.post(
'paste_your_url', { cash }
);
res.redirect(`/?cash=${cash}&price=${response.data.price}`);
} catch (err) {
console.log(err);
}
});
app.listen(3000);
When the user enters the page /, Express renders index.ejs view without price information.
When the user submits the form to backend, Express:
reads the data,
requests 3rd party API,
reads the price from 3rd party response,
redirects user back to / with values in query string ?cash=<value>&price=<value>. This let Express render index.ejs with price information.
Also, I used axios instead of request, because it makes code more readable and easier (due to async/await).
I have recently started picking up Node.js with the Express framework. I created a simple server and attached an HTML file with a form consisted of a single button of type submit which was supposed to send a post request to the server. It doesn't give me any errors but when I try to log a message to the console upon pressing the submit button, nothing happens. I am pretty sure it has something to do with the HTML form syntax but I can never be too sure. Here is the HTML:
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<form class="test" action="http://localhost:8000/example" method="post">
<input type="submit" name="but" value="Press me">
</form>
</body>
</html>
Here is the Express code:
const http = require("http");
const app = require("express")();
const path = require('path');
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/example", (req, res) => {
console.log("pressed");
});
app.listen(8000, ()=>{
console.log("Running at 8000");
});
It's occurs because app.use () is treated as middleware for your application. To work properly you should use app.get (). Here is more detailed explanation. Other alternative is provide your html as an static content, you can see more about here.
To work properly you should change your code to this:
app.get("/", (req, res) => {
res.sendFile(__ dirname + "/index.html");
});
You can also modify your HTML to this:
<form class="test" action="/example" method="post">
Because is in the same host. You just use complete url when performing action to other host.
Change this...
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
to this...
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
I want to save the information captured from an html form in a MongoDB database, I have the following code:
<!DOCTYPE html>
<html>
<head>
<title>Intro to Node and MongoDB</title>
</head>
<body>
<h1>Into to Node and MongoDB</h1>
<form method="post" action="/addname">
<label>Enter Your Name</label><br>
<input type="text" name="firstName" placeholder="Enter first name..." required>
<input type="text" name="lastName" placeholder="Enter last name..." required>
<input type="submit" value="Add Name">
</form>
</body>
</html>
And the following javascript code would be my app.js
var express = require("express");
var app = express();
var port = 3000;
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var mongoose = require("mongoose");
/*
mongoose.Promise = global.Promise;mongoose.connect("mongodb://localhost:27017/node-demo");
*/
var promise = mongoose.connect('mongodb://localhost:27017/node-demo', {
useMongoClient: true,
/* other options */
});
var nameSchema = new mongoose.Schema({
firstName: String,
lastName: String
});
var User = mongoose.model("User", nameSchema);
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/addname", (req, res) => {
var myData = new User(req.body);
myData.save()
.then(item => {
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
app.listen(port, () => {
console.log("Server listening on port " + port);
});
Apparently the post request is working, filling in the fields and pressing the input type submit, however when checking the database is empty, just as it was when it was created. Does anyone know why I do not save the information?
I run your code here and the app.post was not called. It's because you're using app.use to send the index.html. app.use is used to bind middleware to your application. Instead, you should use app.get, which tells express to listen for requests to / and run the function when it sees one.
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
I stuck in figuring out how client file find routes function in express. My app structure is like that,
|-root
|--public
|---files
|---scripts
|---css
|--views
...
The client side html is as blow, which is in /public/files. It can be rendered to http://localhost:3000/files/like_animal.html correctly.
<html>
<body>
<form action="/handleForm" method="post">
name: <input name="usename"><br>
I like <input name="animal"><br>
<input type="submit" value="Go">
</form>
</body>
</html>
The js file is like that,
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname + 'public')));
console.log('start');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/handleForm', (req, res) => {
var name = req.body.name;
var animal = req.body.animal;
console.log(name + " " + animal);
res.send('Thank you');
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
Now I am not sure where I should put this js file in. I tried to put it in /public/scripts or root, even also in /public/files. But nothing works. Every time I submit the form, the browser always show Cannot POST /handleForm. As a one-week newbie in express, I am totally lost. Any hint will be appreciated. Thanks a lot.
You should put your script at the root then specify the public's path like this.
app.use(express.static(path.join(__dirname, 'public')));
Another note, app.use is used to make a middleware. You should define your route using app.post.
app.post('/handleForm', (req, res) => {
// ...
});
I tried to build a simple node application with routes, but it gives a 404 network error as it's unable to post. Can someone please point out my mistake and correct it?
First I created a directory sampProj, then in it, I've a file - appl.js and a directory routes. Inside routes directory, I've a directory routes and a file main.js. Again inside mainCode directory, I've 3 files - main.js, server.js and index.html.
Sorry for the complicated directions, I wanted to test out small and then start building on it. I want to mention that this code with just server.js and index.html worked without the routes, i.e server.js uses app.post and app.get etc. instead of the corresponding router methods which I've shown below.
So here's the code for the application:
appl.js:
var express = require('express');
var bodyParser = require('body-parser');
var app = module.exports.app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false}));
// parse application/json
app.use(bodyParser.json());
// Adding routes
var server = require(__dirname + '/routes/main');
var mainCode = require(__dirname + '/routes/mainCode/main.js');
app.use('/Service', server);
app.use('/Service/mainCode', mainCode);
// Catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/* Error Handlers */
// It will print the Stacktrace of error
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.send({
message: err.message,
error: err
});
});
}
app.listen(3000,function(){
console.log("Working on port 3000");
});
routes/main.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('<code>Welcome to Service</code>');
});
module.exports = router;
mainCode/main.js:
var express = require('express');
var router = express.Router();
var server = require(__dirname + '/server');
router.use('/server', server);
module.exports = router;
mainCode/index.html
<html>
<head>
<title>Form Data</title>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data" action="/" method="post">
<input id = "userPhotos" type="file" name="userPhotos" multiple />
<input type='text' id='random' name='random'><br>
<input type="submit" value="Upload" name="submit">
</form>
</body>
</html>
mainCode/server.js:
var express = require("express");
var router = express.Router();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + file.originalname);
}
});
var upload = multer({ storage : storage }).any();
router.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});
router.post('/',function(req,res){
console.log("posted");
console.log("posted");
console.log(req.body);
upload(req,res,function(err) {
if(err) {
console.error(err);
return res.end("Error uploading file.");
}
console.log(req.body);
console.log(req.files);
res.end("File is uploaded");
});
});
module.exports = router;
Once I open localhost:3000/Service/mainCode/server in a browser, a form is displayed with one text input, but if I submit data, it's redirecting to localhost:3000 with error 404 displayed on the screen.
If you downvote this, please tell me why you're doing so, and in what way I can improve the question.
You access the form via the URL:
http://localhost:3000/Service/mainCode/server
right?
In your mainCode/server.js you set the get as well as the post handling for the same URL.
So why do you call the root directory in mainCode/index.html on form submit:
<form id="uploadForm" enctype="multipart/form-data" action="/" method="post">
it should be:
<form id="uploadForm" enctype="multipart/form-data" action="/Service/mainCode/server" method="post">
as far as I understand.
Usually if you want to send a formular to the same URL you would just leave the action attribute out like:
<form id="uploadForm" enctype="multipart/form-data" method="post">
EDIT: Turned out that it solved the problem for the OP combined with the removing of the attribute enctype, which leads to the default application/x-www-form-urlencoded method.
But as the OP wanted to submit a file in the first place, he had to exchange the body-parser module with multer and set the enctype to multipart/form-data again.
Documentation of multer:
https://github.com/expressjs/multer