NodeJS - Getting form post data - node.js

I am a newbie in NodeJs.
Trying to figure out why the following code is not working for me.
I am basically trying to do a simple post from an HTML file.
It works fine if I send the post request from curl, or if I use AJAX post.
Would like to know what's wrong with the following post.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post" action="http://localhost:3000/">
<table>
<tr>
<td><input type="text" id="txtOne"/></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit Data">
</td>
</tr>
</table>
</form>
</body>
</html>
My node.js file is
var express = require("/usr/local/bin/node_modules/express");
var bodyParser = require("/usr/local/bin/node_modules/body-parser");
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/',function(req,res){
res.sendfile("mypage.html");
});
app.post('/',function(req,res){
var str = req.body.txtOne;
console.log("From Client POST request: Text = " + str);
res.end(str);
});
app.listen(3000);
I am getting str value as undefined.

First of all, your form field needs a name value instead of a id.
So change
<td><input type="text" id="txtOne"/></td>
to
<td><input type="text" name="txtOne"/></td>

var str = req.body.txtOne;
you are searching for the input that has name="txtOne"
id works only for the DOM
<td><input type="text" name="txtOne"/></td>

Related

Rows is not Iterable Error in EJS response

Hello I am getting an error in my EJS response file I am trying to display my form data that makes a request to my database on the server side and I am getting this error here is the Form Code and the Server side
<body>
<form method="POST" action="/user/post">
<table>
<tr>
<td>Username</td>
<td><input type="text" name="username" ></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save" ></td>
</tr>
</table>
</form>
</body>
<html>
<head>
<title>Message Logs</title>
</head>
<body>
<div>
<% for (var row of rows) { %>
<div><%= row.username %> <%= row.message %></div>
<% } %>
</div>
</body>
</html>
app.post('/user/post',function(req,res){
db.all(`SELECT * FROM messages WHERE name='${req.body.username}'`, (err, rows) => {
if (err) {
console.error(err.message);
}
res.render('userinfo', { rows: rows });
});
I am expecting it to display my database query it is an sqlite3 database and the table name is : messages with the fields : username , message
Found the error just a syntax mistake in the db query should have been WHERE username not where name

tableau extension server could not respond due to malformed response

I am trying to develop my very first Tableau extension for Tableau server. I am developing it locally.
It is almost a Hello World kind of extension.
When I try to add an extension, it throws me an error "Request Rejected By Server"
It is a node.js app and running perfectly fine.
Here is my server.js
const express = require('express');
const app = express();
const process = require('process');
app.get('/', async function(req, res){
res.sendFile(__dirname + "/public/datasources.html");
});
const listener = app.listen(3030, () =>{
console.log("App is listening on port " + listener.address().port);
Here is my datasources.html.. This is one of those provided as sample from tableau.. I just added js part of it at the end. All in one file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Datasources Sample</title>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
<!-- Extensions Library (this will be hosted on a CDN eventually) -->
<script src="https://extensions.tableauusercontent.com/resources/tableau.extensions.1.latest.min.js"></script>
<!-- Our extension's code -->
</head>
<body>
<div class="container">
<!-- DataSources Table -->
<div id="dataSources">
<h4>All DataSources</h4>
<div class="table-responsive">
<table id="loading" class="table">
<tbody><tr><td>Loading...</td></tr></tbody>
</table>
<table id="dataSourcesTable" class="table table-striped hidden">
<thead>
<tr>
<th>DataSource Name</th>
<th>Auto Refresh</th>
<th style="width: 100%">Info</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- More dataSource info modal -->
<div class="modal fade" id="infoModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">DataSource Details</h4>
</div>
<div id="dataSourceDetails" class="modal-body">
<div class="table-responsive">
<table id="detailsTable" class="table">
<tbody>
<tr>
<td>DataSource Name</td>
<td id="nameDetail"></td>
</tr>
<tr>
<td>DataSource Id</td>
<td id="idDetail"></td>
</tr>
<tr>
<td>Type</td>
<td id="typeDetail"></td>
</tr>
<tr>
<td>Fields</td>
<td id="fieldsDetail"></td>
</tr>
<tr>
<td>Connections</td>
<td id="connectionsDetail"></td>
</tr>
<tr>
<td>Active Tables</td>
<td id="activeTablesDetail"></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Wrap everything in an anonymous function to avoid polluting the global namespace
(function () {
$(document).ready(function () {
tableau.extensions.initializeAsync().then(function () {
// Since dataSource info is attached to the worksheet, we will perform
// one async call per worksheet to get every dataSource used in this
// dashboard. This demonstrates the use of Promise.all to combine
// promises together and wait for each of them to resolve.
let dataSourceFetchPromises = [];
// Maps dataSource id to dataSource so we can keep track of unique dataSources.
let dashboardDataSources = {};
// To get dataSource info, first get the dashboard.
const dashboard = tableau.extensions.dashboardContent.dashboard;
// Then loop through each worksheet and get its dataSources, save promise for later.
dashboard.worksheets.forEach(function (worksheet) {
dataSourceFetchPromises.push(worksheet.getDataSourcesAsync());
});
Promise.all(dataSourceFetchPromises).then(function (fetchResults) {
fetchResults.forEach(function (dataSourcesForWorksheet) {
dataSourcesForWorksheet.forEach(function (dataSource) {
if (!dashboardDataSources[dataSource.id]) { // We've already seen it, skip it.
dashboardDataSources[dataSource.id] = dataSource;
}
});
});
buildDataSourcesTable(dashboardDataSources);
// This just modifies the UI by removing the loading banner and showing the dataSources table.
$('#loading').addClass('hidden');
$('#dataSourcesTable').removeClass('hidden').addClass('show');
});
}, function (err) {
// Something went wrong in initialization.
console.log('Error while Initializing: ' + err.toString());
});
});
// Refreshes the given dataSource.
function refreshDataSource (dataSource) {
dataSource.refreshAsync().then(function () {
console.log(dataSource.name + ': Refreshed Successfully');
});
}
// Displays a modal dialog with more details about the given dataSource.
function showModal (dataSource) {
let modal = $('#infoModal');
$('#nameDetail').text(dataSource.name);
$('#idDetail').text(dataSource.id);
$('#typeDetail').text((dataSource.isExtract) ? 'Extract' : 'Live');
// Loop through every field in the dataSource and concat it to a string.
let fieldNamesStr = '';
dataSource.fields.forEach(function (field) {
fieldNamesStr += field.name + ', ';
});
// Slice off the last ", " for formatting.
$('#fieldsDetail').text(fieldNamesStr.slice(0, -2));
dataSource.getConnectionSummariesAsync().then(function (connectionSummaries) {
// Loop through each connection summary and list the connection's
// name and type in the info field
let connectionsStr = '';
connectionSummaries.forEach(function (summary) {
connectionsStr += summary.name + ': ' + summary.type + ', ';
});
// Slice of the last ", " for formatting.
$('#connectionsDetail').text(connectionsStr.slice(0, -2));
});
dataSource.getActiveTablesAsync().then(function (activeTables) {
// Loop through each table that was used in creating this datasource
let tableStr = '';
activeTables.forEach(function (table) {
tableStr += table.name + ', ';
});
// Slice of the last ", " for formatting.
$('#activeTablesDetail').text(tableStr.slice(0, -2));
});
modal.modal('show');
}
// Constructs UI that displays all the dataSources in this dashboard
// given a mapping from dataSourceId to dataSource objects.
function buildDataSourcesTable (dataSources) {
// Clear the table first.
$('#dataSourcesTable > tbody tr').remove();
const dataSourcesTable = $('#dataSourcesTable > tbody')[0];
// Add an entry to the dataSources table for each dataSource.
for (let dataSourceId in dataSources) {
const dataSource = dataSources[dataSourceId];
let newRow = dataSourcesTable.insertRow(dataSourcesTable.rows.length);
let nameCell = newRow.insertCell(0);
let refreshCell = newRow.insertCell(1);
let infoCell = newRow.insertCell(2);
let refreshButton = document.createElement('button');
refreshButton.innerHTML = ('Refresh Now');
refreshButton.type = 'button';
refreshButton.className = 'btn btn-primary';
refreshButton.addEventListener('click', function () { refreshDataSource(dataSource); });
let infoSpan = document.createElement('span');
infoSpan.className = 'glyphicon glyphicon-info-sign';
infoSpan.addEventListener('click', function () { showModal(dataSource); });
nameCell.innerHTML = dataSource.name;
refreshCell.appendChild(refreshButton);
infoCell.appendChild(infoSpan);
}
}
})();
</script>
</body>
</html>
And here is my trex extension file.
<?xml version="1.0" encoding="utf-8"?>
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
<dashboard-extension id="com.tableau.extensions.samples.datasources" extension-version="0.6.0">
<default-locale>en_US</default-locale>
<name resource-id="name"/>
<description>DataSources Sample</description>
<author name="tableau" email="github#tableau.com" organization="tableau" website="https://www.tableau.com"/>
<min-api-version>0.8</min-api-version>
<source-location>
<url>http://MACHINE_NAME:3030/</url>
</source-location>
<icon>iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg==</icon>
<permissions>
<permission>full data</permission>
</permissions>
</dashboard-extension>
<resources>
<resource id="name">
<text locale="en_US">DataSources Sample</text>
</resource>
</resources>
</manifest>
Do I have to do something on Tableau server side to make it work?
This might be because you are using http:// without localhost. That is not allowed. I'm not sure why the error message is so unhelpful, but it could be that the error coming back from server is not formatted well for the client error box. Hard to know without logs. :)
Try out either switching to hosting your extension from http://localhost or create a self-signed certificate with SAN, add that to your trust store and host from https:// instead.

Node.js (express framework): Post method not working

I am able to run the Get method and HTML form also visible on browser using Get method but when I am clicking on submit button nothing is happening, no error nothing. it shows the same HTML form page.
HTML code:
<!DOCTYPE html>enter code here
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Calculator</title>
</head>
<body>
<form action="/" method="post">
<h1>Calculator</h1>
<input type="text" name="num1" placeholder="Number 1">
<input type="text" name="num2" placeholder="Number 2">
<button action="/" type="button" name="button">Submit</button>
</form>
</body>
</html>
Node Js code:
//jshint esversion:6
const express=require("express");
const app=express();
app.get("/", function(req,res){
res.sendFile( __dirname+"/index.html");
});
app.post("/", function(req,res){
res.send("Thanks for post");
});
app.listen(3000, function(){
console.log("Server Started On Port 3000");
});
Your button type should be Submit
<button type="submit" value="Submit">Calculator</button>

GET method form with ExpressJS - multiple app.get

I want to make a simple login form.
This is the relevant code:
app.get('/login' , (req,res)=>{
app.use(express.static('login'));
res.render(__dirname + '/login/index.ejs');
/*This is load the login page*/
});
index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login</title>
</head>
<body>
<h1>Login</h1>
<form action="/" method="GET">
<input type="text" name="email" placeholder="email">
<input type="password" name="password" placeholder="password">
<input type="submit" value="login">
</form>
</body>
</html>
You can see the form is GET method because I don't create/update anything. If I used app.post for detecting the parameters I've used app.post and it was working fine.
But how I handle two app.get ? one for load the page, the second for handle the html form ?
For example:
app.get('/login' , (req,res)=>{
console.log(req.query);
}
Thanks !
I recommend that instead of using the GET method for both the login and the displaying of your website you make your form method POST instead of GET. Then use multer in your express app as a way to parse the received form data.
<form action="/" method="POST">
const multer = require('multer');
const upload = multer();
app.use(upload.array());
app.post('/login', function(req, res){
console.log(req.body);
res.send("recieved your request!");
});

getting user input from form using express js and body parser

I am having problems getting user input from form.
could you please tell where am I going wrong??
here's the add-employee.html code
<!DOCTYPE HTML>
<html>
<head>
<title>Add Employee</title>
<!--<script type="text/javascript" src="main.js"></script> -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<table>
<form action="/form" method="post">
<tr>
<th>
<label>Name:</label>
<input type="text" name="name">
</th>
<th>
<label>Designation:</label>
<input type="text" name="designation">
</th>
<th>
<label>PAN No:</label>
<input type="text" name="pan">
</th>
<th>
<label>Aadhar No:</label>
<input type="text" name="aadhar">
</th>
<th>
<label>Bank A/c:</label>
<input type="text" name="bank">
</th>
<th>
<label>Basic Salary:</label>
<input type="text" name="basicsalary">
</th>
<th>
<label>Other Allowance:</label>
<input type="text" name="allowance">
</th>
<th>
<label>ESI No:</label>
<input type="text" name="esi">
</th>
<th>
<label>UAN No:</label>
<input type="text" name="uan">
</th>
</tr>
<tr>
<td>
<input type="submit" name="submit_button">
</td>
</tr>
</form>
</table>
</body>
</html>
And here's the link to the server.js code which I am using to run the app.
https://github.com/silentarrowz/payroll/blob/master/server.js
when I submit the form I am expecting to get a response of
'employee' + name + 'added'
But I am getting the result as " employee undefined added ".
now, why is this happening?
where am I going wrong?
In your server.js you have the line.
app.use(bodyParser.json());
This means that your server can only read JSON data in requests. However, unless you are using javascript/jquery to send the form to the server, the data is never formatted as JSON. Instead browsers use urlencoded or multipart formats to send the form. multipart is normally only used when you are sending files with your form so it is most likely using urlencoded format.
That means that you need to include a body parser for the urlencoded format.
Simply change it so we have the urlencoded parser below the json parser like this:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
However if you will be sending files with your forms, you must parse the request using a module like multiparty.

Resources