I have a super simple form within a NodeJS/ExpressJS app which fails to post.
The app.js code (I call it server.js) looks like this.
var express = require('express');
var fs = require('fs');
var path = require('path');
var urlEncoded = require('urlencoded-request-parser');
var bodyParser = require('body-parser');
var server = express();
var port = process.env.port || 1337;
server.use(urlEncoded());
server.use(bodyParser.urlencoded({extended: true}));
var routePath="./routes/";
fs.readdirSync(routePath).forEach(function(file) {
var route=routePath+file;
require(route)(server);
});
server.set('view engine', 'ejs');
server.set('views', __dirname);
server.listen(port);
My post form (post.ejs)
<form method="post" action="post-put">
<fieldset>
<!-- Form Name -->
<legend>Which Test Type</legend>
<!-- Multiple Radios (inline) -->
<div class="form-group">
<label class="col-md-2 control-label" for="TestType">Please test our</label>
<div class="col-md-4">
<label class="radio-inline" for="TestType-0">
<input type="radio" name="SoftwareTestType" id="TestType-0" value="SoftwareTest" checked="checked">
Software
</label>
<label class="radio-inline" for="TestType-1">
<input type="radio" name="HardwareTestType" id="TestType-1" value="HardwareTest">
Hardware
</label>
</div>
</div>
</fieldset>
<input type='submit' class="btn btn-default" id='submit' value='Submit your Test'/>
</form>
The results are shown in this page (post-results.ejs)
<%= Test %>
I have two routes (post-get.js)
module.exports = function(server){
server.get('/post', function(req,res){
res.render('./views/test/post.ejs',{
});
});
}
and (post-puts.js)
module.exports = function(server){
server.post('post-put', function(req,res){
console.log("In Submission POST")
var TestType = "";
if(req.body.HardwareTestType == true)
TestType = "Hardware";
else
TestType = "Software";
res.render('./views/test/post-results.ejs',{
Test: TestType
});
});
}
When I click on submit button, developer tools shows this:
This is driving me insane. Does anyone know how to get this to post the results to the post-results.ejs file. The layout of the filesystem for the application looks like this:
UPDATE:
Both the form and the router have same paths "post-puts".
In the post-puts route there is a console.log() ... but it is NOT called.
I think it could still be the application type as shown in the image two up (Developer Tools)
When a "thing" has only 1 function, saying it does not work is specific - if I could be more specific I would know what the problem was and fix it.
This HTML URL path <form method="post" action="/post-put"> doesn't match this path in your code server.post('/test/post-put'. Make them match and it will work.
remove slash from post-put
<form method="post" action="post-put">
SOLVED
The resolution to the above problem was the following.
1) I changed the route back to "/post-put" in the form Action and in the Route file.
2) I added enctype="multipart/form-data" to the form.
So the form now looks like
<form method="post" action="/post-put" enctype="multipart/form-data">
<fieldset>
<!-- Form Name -->
<legend>Which Test Type</legend>
<!-- Multiple Radios (inline) -->
<div class="form-group">
<label class="col-md-2 control-label" for="TestType">Please test our</label>
<div class="col-md-4">
<label class="radio-inline" for="TestType-0">
<input type="radio" name="TestType" id="TestType-0" value="SoftwareTest" checked="checked">
Software
</label>
<label class="radio-inline" for="TestType-1">
<input type="radio" name="TestType" id="TestType-1" value="HardwareTest">
Hardware
</label>
</div>
</div>
</fieldset>
<input type='submit' class="btn btn-default" id='submit' value='Submit your Test'/>
</form>
ALTERNATIVE SOLUTION
Keep the form enctype as enctype="application/x-www-form-urlencoded"
In App.js (my server.js)
Remove app.use(bodyparser.urlencoded());
Change app.use(bodyParser.urlencoded({extended: true})); to server.use(bodyParser.urlencoded());
Now the POST method of the form works!
Thanks to those who tried to help.
Related
I'm trying to use post with express and bodyparser to insert data into MYSQL from a form in a ejs file. It keeps returning null, so it seems that my data is not parsed from the form to my backend.
Could you please help?
Here is my server.js
app.use(express.json({ limit: '100mb' }));
app.use(express.urlencoded({ limit: '100mb', extended: false }));
dotenv.config();
// Set the default views directory to html folder
app.set('views', path.join(__dirname, 'html'));
// Set the folder for css & java scripts
app.use(express.static(path.join(__dirname,'css')));
app.use(express.static(path.join(__dirname, 'node_modules')));
// Set the view engine to ejs
app.set('view engine', 'ejs');
app.use('/', routes);
app.listen(3000, () => {
console.log(`Server is running at ${process.env.SERVER_PORT}`);
});
my index.js
router.post('/save', (req, res) => {
const formData = { username : req.body.username, account : req.body.account, email : req.body.email,
address : req.body.address, start_date : req.body.start_date, picture : req.body.picture,
request : req.body.request };
const sqlPut = "INSERT INTO dbTable ?";
const query = dbconn.conn.query(sqlPut, formData, (err, results) => {
if(err) throw err;
res.redirect('/about')
})
})
Here is my ejs file with the form.
<div class="container" >
<form id="contact" action="/save" method="post">
<h3>New scholar form</h3>
<fieldset>
<input placeholder="username" id="username" type="text" tabindex="1" required autofocus>
</fieldset>
<fieldset>
<input placeholder="account" id="account" type="text" tabindex="2" required>
</fieldset>
<fieldset>
<input placeholder="email" id="email" type="email" tabindex="3" required>
</fieldset>
<fieldset>
<input placeholder="bnc_address" id="bnc_address" type="text" tabindex="4" required>
</fieldset>
<fieldset>
Scholar start date <input placeholder="start_date" type="date" tabindex="4" required>
</fieldset>
<fieldset>
<input placeholder="picture" id="picture" type="text" tabindex="4" required>
</fieldset>
<fieldset>
<textarea placeholder="Scholar request..." id="request" tabindex="5" required></textarea>
</fieldset>
<fieldset>
<button name="submit" type="submit" id="contact-submit">Submit</button>
</fieldset>
</form>
I can retrieve data from the database and post it just fine. I just haven't figured this one out.
I haven't posted here in a while, so bear with me
You need to change this line:
app.use(express.urlencoded({ limit: '100mb', extended: true }));
Parses the text as URL encoded data(which is how browsers tend to send form data from regular forms set to POST) and exposes the resulting object (containing the keys and values) on req.body.
I imported body-parser without using it. After I removed the import it started working.
Removed this, even though it was not used, it started working after:
const bodyParser = require("body-parser");
I am using nodejs with express and ejs.
Every one on internet ask how to pass value from node to the view, but what about the opposite?
For example, I ask my user to input a string in a form, when the user clicks the button, how can I get this string without passing it as a parameter in the url?
The form:
<div class="container">
<form style="width:50%">
<div class="form-group">
<label for="text">Name of the product</label>
<input type="text" class="form-control" id="pName">
</div>
<div class="form-group">
<label for="text">Reciever</label>
<input type="text" class="form-control" id="reciever">
</div>
<div class="form-group">
<label for="text">Location</label>
<input type="text" class="form-control" id="location">
</div>
<!-- <div class="checkbox">
<label><input type="checkbox"> Remember me</label>
</div>-->
<button type="submit" class="btn btn-default">Submit</button>
</form>
The app.js
var express = require('express');
var app = express();
//ALL GLOBAL VARIABLES
var port = 8080;
app.get('/', function(req, res) {
res.render('index.ejs');
});
app.get('/barcode', function(req,res) {
res.render('barcode.ejs');
});
app.listen(port);
I know I can do this:
app.get('/url/:parameter', function(req.res) {
var foo = req.params.parameter;
}
But if I don't want to use the URL, is it possible to retrieve the data?
Use POST as a method for your html form
<form action="/myapi" method="post">
<input type="text" class="form-control" id="pName" name="pName">
<button type="submit" class="btn btn-default">Submit</button>
</form>
And then handle the client form "action" with app.post on the back end
app.post('/myapi', function(req, res) {
res.send('The pName is "' + req.body.pName + '".');
});
You can use POST method instead of GET. You need to change the route in your Express to
app.post('/url', function(req.res))
and add a method on your form
<form style="width:50%" method="POST">
If you use a POST request the parameters are not part of the URL. E.g.
app.post('/path', function(req, res) {
...
//You can retrieve the parameters of the POST request here
]);
You'll need the body-parser module to be able to get the POST parameters. Here's an answer about how to get the POST parameters once you've set up the route.
Your form should have a method and and action:
<form action="/path" method="POST">...</form>
From your question, In general if you want to get a value from the unique id, you will store that value as a global variable. so you can easily get the current user and user related details.
I am trying to show my form data to another html page. This is my server.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var path=require('path');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, '/')));
app.post('/myaction.html', function(req, res) {
res.send('You sent the name "' + req.body.name + '".');
});
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
And this is my 'index.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Demo Form</title>
</head>
<body>
<div id="contact">
<h1>Enter the values</h1>
<form action="/myaction.html" method="post">
<fieldset>
<label for="name">Name:</label>
<input type="text" id="name" name="name" placeholder="Enter your full name" />
<label for="email">Email:</label>
<input type="email" id="email" placeholder="Enter your email address" />
<label for="message">Message:</label>
<textarea id="message" placeholder="What's on your mind?"></textarea>
<input type="submit" value="Send message" />
</fieldset>
</form>
</div>
</body>
</html>
Now, it is working properly and the name is reflecting in the myaction.html page. But I want to stylize the 'myaction.html' page a bit and make it look more presentable. Is there any way to add more html tags and text to the page or to display the form data in an already existing page?
Use a template engine. A good one is EJS. First you have to use npm install ejs and then app.set('view engine', 'ejs'); inside your server.js . After that you will be able to create a new folder in your project named views and inside you can create index.ejs and other views files. Inside your server.js you can use res.render('index.ejs', {data: aJavascriptVariable, data1: moreVars}); . Finally to use this variables inside the .ejs files you can use <%= data %> or <%= data1 %>. Of course html can be written inside a .ejs file.
Okay, here is my form:
<form action="/measure" method="post">
<input type="file" name="thisfile"/>
<input type="submit" value="Give us that file!"/>
</form>
And my server:
var express = require("express"),
multer = require('multer'),
app = express(),
upload = multer({ dest: "./uploads/" });
app.post("/measure", upload.single("thisfile"), function (req, res) {
console.log(req.file);
//other stuff
});
When I submit the form to my server, req.file is undefined.
Wow, wrote you code from scratch assuming a few things but I found the error. In the Multer documentation, it says that Multer will not process a form that is not multipart. So you have to add that to your form (enctype="multipart/form-data"):
<form action="/measure" method="post" enctype="multipart/form-data">
<input type="file" name="thisfile"/>
<input type="submit" value="Give us that file!"/>
</form>
With that it should work. Let me know if this helped you.
PS: Here is the documentation: https://www.npmjs.com/package/multer
I'm a little be confused when it comes to calling APIs over node.js.
I have a server running node js where I can install frameworks like the one for chargebee.
I created a html page where I make subscriptions etc. Now I would want to call the corresponding chargebee function to make the subscription.
If I try to load chargebee with require('chargebee')it failes. I can only load it in the server js.
So how would it be possible for me to use the functionalities of chargebee?
Is it possible that I invoke a function from chargbee by a click on the button? Do i have to provide this function by express?
I think I did not understand the difference between client side code and server side code when it comes to node.js.
How can function on the server side be invoked by clicks on html buttons for example?
In order to trigger request from client side you can use forms or AJAX. Here is an example with express framework in which form is used to trigger request and create subscription in chargebee
Client-Side Code:
<html>
<body>
<form action="/subscribe" method="post">
<label for="name">First Name:</label>
<input type="text" id="name" name="customer[first_name]" placeholder="first name" />
<br />
<label for="name">Last Name:</label>
<input type="text" id="name" name="customer[last_name]" placeholder="last name" />
<br />
<label for="email">Email:</label>
<input type="email" id="email" name="customer[email]" placeholder="Enter your email address" />
<br />
<input type="submit" value="Create Profile" />
</form>
</body>
</html>
Node-Server code:
var express = require('express');
var chargebee = require("chargebee");
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
chargebee.configure({site : "<<site_name>>",
api_key : "<<api_key>>"
app.get('/', function(req, res){
res.sendFile(__dirname + '/form.html');
});
app.post('/subscribe', function(req, res){
var params = req.body;// getting form params as JSON
params['plan_id']='enterprise'; // plan id that is present in your Chargebee site
chargebee.subscription.create(params).request(function(error,result){
if(error){
//handle error
console.log(error);
}else{
console.log(result);
var subscription = result.subscription;
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('Successfully created subscription\n\n' + 'id :: '+ subscription.id);
res.end();
}
});
});
app.listen(3000);
console.log("server listening on 3000");
It is possible with chargebee v3 . Hope This will solve your query
<!DOCTYPE html>
<html>
<head>
<title>chargebee Example</title>
<script src = "https://js.chargebee.com/v2/chargebee.js" data-cb-site = "your site name" > </script>
</head>
<body>
<!-- for creating subscription -->
<a href="javascript:void(0)" data-cb-type="checkout" data-cb-plan-id="30" >subscribe</a>
<!-- for managing portal -->
<a href="javascript:void(0)" data-cb-type="portal" >Manage account</a>
</body>
</html>