node.js, express no body object inside my app.post request - javascript

I have a problem with node.js and express, I try to get infos from a post coming from an html file, and the problem is that when I do a console.log of my request i don't have any information inside my req.body.
I did a console.log(req.body) at the beginning of my app.post("/render_pdf" ....) and all i've got is a empty object.
I don't know if it's coming from my .html or my server.js but i don't understand where the problem is coming from. I used multer to upload a pdf based on a html select and it's working .. so i don't have any solutions on this.
my html (with a bit of php) :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ebook-stage</title>
<link href="public/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<?php
$pdo=new PDO('mysql:host=localhost; dbname=ebook-stage; charset=utf8',
'root', '');
$statement=$pdo->prepare("SELECT * FROM publication");
$statement->execute();
?>
<div class="jumbotron">
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<form method="POST" action="http://localhost:8090/create_pdf" enctype="multipart/form-data">
<label for="extractor">Extracteur PDF</label>
<br><select class="form-control" name="extractor" id="extractor">
<option name="pdf2json" value="pdf2json">PDF2JSON</option>
<option name="pdfextract" value="pdfextract">PDFEXTRACT</option>
<option name="textract" value="textract">TEXTRACT</option>
</select>
<br><label for="file">Upload Pdf</label>
<input id="file" type="file" name="file">
<br><input type="submit" name="submit" id="submit" class="exec btn btn-success" value="Exécuter">
</form>
</div>
<div class="col-md-3">
<form method="POST" action="http://localhost:8090/render_pdf">
<label for="require">PDF a afficher</label>
<br><select class="form-control" name="require" id="require">
<?php while ($rendername = $statement->fetchObject()):?>
<option name="<?= $rendername->name ?>"><?= $rendername->name ?></option>
<?php endwhile; ?>
</select>
<?php while ($rendername = $statement->fetchObject()):?>
<input type="hidden" name="<?= $rendername->id ?>" id="id">
<?php endwhile; ?>
<br><input type="submit" name="envoi" id="envoi" class="exec btn btn-success" value="Afficher">
</form>
</div>
</div>
</div>
</div>
</body>
</html>
my pdf-rest.js :
var mysql = require('mysql');
var bodyParser = require('body-parser');
var request = require('request');
var jsonParser = bodyParser.json();
var http = require('http');
var fs = require('fs');
var Promise = require('bluebird');
var multer = require('multer');
var textract = require('textract');
var pdf_extract = require('pdf-extract');
var PDFParser = require("pdf2json");
var pdfParser = new PDFParser();
var inspect = require('eyes').inspector({maxLength:20000});
var optionsExtract = {
type: 'ocr' // perform ocr to get the text within the scanned image
};
var express = require('express');
module.exports = function(app){
function requireDB(){
connection.connect();
connection.query('SELECT * FROM publication WHERE id = 105', function(err, rows, fields){
console.log(err);
res.end(rows[0].id+rows[0].name);
});
}
app.post('/render_pdf', jsonParser, function (req, res) {
console.log(req);
res.end('affichage pdf');
});
var destination = "uploads";
app.post('/create_pdf', jsonParser, function (req, res) {
console.log(req.body);
var connection = mysql.createConnection({
user: 'root',
password: '',
host: 'localhost',
port: 3306,
database: 'ebook-stage'
});
var filename = "" + Date.now() + ".pdf";
var filePath = "C:\\wamp64\\www\\ebook-stage\\backend\\rest\\uploads\\" + filename;
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, destination);
},
filename: function (req, file, cb) {
cb(null, filename);
}
});
var upload = multer({storage: storage}).single('file');
function uploadFile() {
console.log('entering upload file');
var uploadFilePromise = new Promise(function (resolve,reject) {
upload(req, res, function (err) {
if (err) {
reject(err);
res.end('error uploading file')
}
else{
console.log('upload resolve');
res.end('pdf uploaded');
console.log(req.body);
resolve(req);
}
});
});
return uploadFilePromise;
}
function insertDB(pdfObject) {
connection.connect();
var insertPublication = {name: pdfObject.originalFilename};
new Promise(function (resolve, reject) {
connection.query('INSERT INTO publication SET ?', insertPublication, function (err, res) {
if (err) {
reject(err);
}
else {
console.log('insertDB publication');
console.log(res);
resolve(res['insertId']);
}
});
}).then(function (pubId) {
pdfObject.text.forEach(function (text) {
var insertContent = {type: 'TXT', content: text};
new Promise(function (resolve, reject) {
connection.query('INSERT INTO content SET ?', insertContent, function (err, res) {
if (err) {
console.log(err);
reject(err)
}
else {
console.log('insertDB content');
console.log(res);
resolve(res['insertId']);
}
});
}).then(function (insertBlock) {
var blockid = {contentid: insertBlock};
new Promise(function (resolve, reject) {
connection.query('INSERT INTO block SET ?', blockid, function (err, res) {
if (err) {
console.log(err);
reject(err);
}
else {
console.log('insertDB block');
console.log(res);
resolve(res['insertId']);
}
});
}).then(function (blockId) {
var linkpublicationids = {blockid: blockId, publicationid: pubId};
connection.query('INSERT INTO linkpublication SET ?', linkpublicationids, function (err, res) {
if (err) {
console.log(err);
return err
}
else {
console.log('insertDB linkpublication');
console.log(res);
}
});
})
});
});
}).catch(function () {
connection.end(function (err) {
console.log(err);
})
});
}
function textractPdf(originalFilename) {
console.log('TEXTRACT PDF');
var textBlockPromise = new Promise(function (resolve, reject){
textract.fromFileWithPath(filePath, function (error, text) {
var result = [{originalFilename: originalFilename}];
if (error) {
console.log('Text is not parsed');
reject(error);
}
else {
console.log('Text is parsed');
result[0].text = [];
result[0].text.push(text);
resolve(result[0]);
console.log('after resolve textract')
}
});
});
console.log('exiting textract');
return textBlockPromise;
}
function extractPdf(originalFilename) {
console.log('EXTRACT PDF');
var textBlockPromise = new Promise(function (resolve, reject){
var result = [{originalFilename: originalFilename}];
processor = pdf_extract(filePath, optionsExtract, function (err) {
if (err) {
console.log('error extract');
reject(err);
}
});
processor.on('complete', function (data) {
var resultsplited = data.text_pages[0].split('\n');
result[0].text = [];
resultsplited.forEach(function(text){
result[0].text.push(text);
});
resolve(result[0]);
});
processor.on('error', function (err) {
console.log('error extract');
inspect(err, 'error while extracting pages');
reject(err);
});
});
return textBlockPromise;
}
function convertPdf2json(originalFilename){
console.log('EXTRACT PDF2JSON');
var textBlockPromise = new Promise(function (resolve, reject){
var result = [{originalFilename: originalFilename}];
result[0].text = [];
pdfParser.on("pdfParser_dataError", function(errData){
reject(errData);
});
pdfParser.on("pdfParser_dataReady", function(pdfData){
pdfData.formImage.Pages.forEach(function(page){
page.Texts.forEach(function(text){
var textparsed = decodeURIComponent(text.R[0].T);
result[0].text.push(textparsed);
});
});
resolve(result[0]);
});
pdfParser.loadPDF(filePath);
});
return textBlockPromise
}
function selectExtractor(req){
console.log(req.body.extractor);
var extractorPromise = new Promise(function (resolve){
if(req.body.extractor == 'textract'){
resolve (textractPdf(req.file.originalname));
console.log('extractor end');
}
else if(req.body.extractor == 'pdfextract'){
resolve(extractPdf(req.file.originalname));
console.log('extractor end');
}
else if (req.body.extractor == 'pdf2json'){
resolve(convertPdf2json(req.file.originalname));
console.log('extractor end');
}
});
return extractorPromise;
}
uploadFile().then(selectExtractor).then(insertDB);
});
};
my server.js :
var express = require('express');
var app = express();
require('./pdf-rest.js')(app);
app.listen(8090);

Just try to update your server file to this actually to use req.body we need to register the middle-ware to all our routes.
var express = require('express');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }))
var app = express();
require('./pdf-rest.js')(app);
app.listen(8090);

As you use multipart/form-data in your form, the body-parser probably won't help here. See body-parser home page:
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
I have no experience with multer, but try using it as it's described in their documentation:
var upload = multer({ dest: 'uploads/' })
app.post('/create_pdf', upload.single('file'), function (req, res, next) {
// req.file is the uploaded file
// req.body will hold the text fields, if there were any
})

Related

Node express sqlite3 . When I use a service for the DB query I get nothing back

I use a sqlite3 database for a node.js express. If I return the request as in the tutorial in router.js it works and I get all the items. Now I have created a service to get the sql from the route (controller). But unfortunately I don't get anything back. I had already tried it with async await in the service. That didn't help either.
my code:
// router.js
const dbService = require("../services/dbService/");
router.get("/users", (req, res, next) => {
try {
res.status(200).send({
data: dbService.getAllUsers();
})
return;
} catch(err) {
next(err);
}
});
// dbService.js
const db = require("../db/database.js");
module.exports = {
getAllUsers() {
const sql = "select * from users";
db.all(sql,[], (err, rows) => {
return {"data": rows};
});
}
}
For simple reasons, I have not included error handling in the code. Why can't I get database values from the service? What do I have to do?
Thanks in advance! Mike
You're running afoul of asynchronous JS. db.all returns results to the callback.
A refactor to use callbacks would look something like:
// router.js
const dbService = require("../services/dbService/");
router.get("/users", (req, res, next) => {
dbService.getAllUsers((err, result) => {
if (err) next(err);
res.json({
data: result;
});
});
});
// dbService.js
const db = require("../db/database.js");
module.exports = {
getAllUsers(cb) {
const sql = "select * from users";
db.all(sql,[], (err, rows) => {
cb(err, rows);
});
}
}
And promises woudl look like:
// router.js
const dbService = require("../services/dbService/");
router.get("/users", async (req, res, next) => {
try {
const result = await dbService.getAllUsers();
res.json({
data: result;
});
} catch (err) {
next(err);
}
});
// dbService.js
const db = require("../db/database.js");
module.exports = {
getAllUsers(cb) {
const sql = "select * from users";
return new Promise((resolve, reject) =>
db.all(sql,[], (err, rows) => {
if (err) reject(err);
resolve(rows);
})
);
}
}

After POST request redirect GET method is called but send file is not working?

When the login button is pressed I send a POST request successfully to my app.js file and just to test try to redirect it with (as instructed) used code 302.
My get request '/' is called and logged
Exist!
did we work? Why does my sendFile not work as I expected? I am relatively new to this so I may be off base on how to do this. My goal is to after submitting a POST transition the client to a new HTML file
const express = require('express');
const { json } = require('express/lib/response');
const app = express();
const fs = require('fs');
app.use(express.json());
app.get('/Register', (req, res) => {
res.sendFile(__dirname + '/Register.html');
});
app.get('/Login', (req, res) => {
res.sendFile(__dirname + '/Login.html');
});
app.get('/RegisterComplete', (req, res) => {
res.sendFile(__dirname + '/RegisterComplete.html');
});
app.get('/', (req, res) => {
console.log('did we work?')
res.sendFile(__dirname + '/Home.html');
});
app.post('/', (req, res) => {
const { username, password } = req.body;
const { authorization } = req.headers;
res.send({
username,
password,
authorization,
});
// fs.readFile('helloworld.txt', 'utf8' , (err, data) => {
// fs.writeFile('helloworld.txt', JSON.stringify(req.body) + data, function (err) {
// if (err) return console.log(err);
// });
// })
console.log(req.body + 'i am not what we need');
});
app.post('/Register', (req, res) => {
fs.readFile('Logins.Json', 'utf8' , (err, data) => {
const obj = req.body;
const testObj = JSON.stringify(obj)
const fileContent = JSON.parse(data)
const newContent = fileContent['User Info']
let test = new Boolean(false)
for (let i = 0; i < newContent.length; i++) {
if(JSON.stringify(newContent[i]) == testObj){
//console.log('Exist!')
test = true
break
}
}
//console.log(req.body);
if (test == true) {
console.log('Exist!')
}else{
newContent.push(obj);
const newData = JSON.stringify(fileContent)
fs.writeFile('Logins.Json', newData, function (err) {
console.log('Created Account!')
if (err) return console.log(err);
})
}
if (err) return console.log(err);
})
res.end()
//console.log(req.body);
});
app.post('/Login', (req, res) => {
res.redirect(302,'/');
fs.readFile('Logins.Json', 'utf8' , (err, data) => {
const obj = req.body;
const testObj = JSON.stringify(obj)
const fileContent = JSON.parse(data)
const newContent = fileContent['User Info']
let test = new Boolean(false)
for (let i = 0; i < newContent.length; i++) {
if(JSON.stringify(newContent[i]) == testObj){
//console.log('Exist!')
test = true
break
}
}
//console.log(req.body);
if (test == true) {
console.log('Exist!')
//login successful
}else{
console.log('Failed')
// login failed
}
if (err) return console.log(err);
})
});
app.listen(7777, () => {
console.log('Our express server is up on port 1000');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>eV Login</title>
</head>
<body>
<form>
<div>
<label>Username</label>
<input type="text" id="user" />
</div>
<div>
<label>Password</label>
<input type="password" id="pass" />
</div>
<button type="submit">Login</button>
</form>
<script>
document.querySelector('button')
.addEventListener('click', (e) => {
e.preventDefault();
const username = document
.querySelector('#user').value;
const password = document
.querySelector('#pass').value;
fetch('/Login', {
method: 'POST',
headers: {
Authorization: 'Vital Gaming',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
}),
})
.then((res) => {
return res.json();
})
.then((data) => console.log(data));
});
</script>
</body>
</html>

How can I update the frontend after waiting for the database in the backend to update in Node.js/Express?

I saw a similar question posted Here, but they are using MEAN-Stack.
I am currently just using a 'setTimeout' function to wait a few seconds before requesting new data from the server using a fetch api to give it time to update but this doesnt feel like the right way to do it. Is there a simple way for the front-end to update only after the database is updated in Express? I am new to Node please forgive me.
app.js:
const express = require('express');
const app = express();
const mysql = require('mysql');
let viewData = {
//html data
}
var pool = mysql.createPool({
connectionLimit : 10,
host: "localhost",
port: 3306,
database: 'testing',
user: "root",
password: "pass"
});
function sql(type) {
if(type == 'select') {
//Select query here
}
if(request == 'addRow') {
//Insert query here
}
}
app.get(`/`, function (req, res) {
res.sendFile('./views/index.html', {root: __dirname});
})
app.post('/api/add', function(req, res){
res.setHeader('Content-Type', 'application/json');
sql('addRow')
});
app.get('/api/viewData', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(viewData));
})
index.js:
function loadData() {
fetch('/api/viewData')
.then(z => z.json())
.then(a => {
//update html
})
}
function postData(a) {
fetch('/api/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
//data to send to app.js
})
}).then(setTimeout(function(){loadData();}, 3000))
}
You should use async and await function
Example: After async/await
async function fun1(req, res){
let response = await request.get('http://localhost:3000');
if (response.err) { console.log('error');}
else { console.log('fetched response');
}
The complete code of our example is shown below:
npm install express jsonschema body-parser promise-mysql
var express = require('express');
var bodyParser = require('body-parser')
var app = express();
var validate = require('./validate')
var mysqlConnection = require('./connectionShare');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const addItem = function(item, connection){
console.log("Adding Item");
return new Promise(function(resolve, reject){
connection.query("INSERT INTO product SET ?", item)
.then(function(result){
resolve(item.seller);
}).catch(function(error){
reject(error);
});
})
}
const findOrCreateUser = function(user,connection){
console.log("Finding User");
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM user WHERE email=" + connection.escape(user.email))
.then(function(results){
if(results.length == 1){
resolve(results[0].id)
} else {
connection.query("INSERT INTO user SET ?", user)
.then(function(results){
resolve(results.insertId);
});
}
}).catch(function(error){
reject(error);
})
})
}
const selectUserItems = function(userID,connection){
console.log("Selecting Items " + userID);
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM product WHERE seller = " + connection.escape(userID))
.then(function(results){
resolve(results);
}).catch(function(error){
reject(error);return;
});
})
}
app.post('/add/product', validate.JsonValidation, mysqlConnection.getConnection, async function(req,res){
var connection = req.connection;
var item = {
name: req.body.name,
price: req.body.price,
width: req.body.width,
height: req.body.height,
added: req.body.added,
image: req.body.image
};
var user = {
username: req.body.seller.username,
email: req.body.seller.email,
votes: req.body.seller.votes
};
try {
item.seller = await findOrCreateUser(user,connection);
var user_id = await addItem(item,connection);
var items = await selectUserItems(user_id, connection);
connection.connection.release();
res.status(200).json(result);
} catch(error) {
res.status(500).end(error);
}
});
process.on('uncaughtException', error => console.error('Uncaught exception: ', error));
process.on('unhandledRejection', error => {console.error('Unhandled rejection: ', error));
app.listen(8000, function () {
console.log('App listening on port 8000')
});

nodejs res.download() file

i'm pretty new to nodejs and stuff, and i;ve been researching on how to upload and download a file from a nodejs server
the upload part works just fine, the problem is the download part
the code i wrote has no errors but however, the file itself is not downloading, i have no idea where i went wrong
here's my uploadss.js file
var express = require('express');
var multer = require('multer');
var path = require('path');
var fs = require('fs');
var app = express();
var router = express.Router();
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, __dirname + '/uploads');
},
filename: function (req, file, callback) {
callback(null, Date.now() + path.extname(file.originalname));
}
});
var upload = multer({ storage : storage }).array('userPhoto',5);
app.set('views', __dirname + '/views');
app.get('/index', function(req, res){
res.render('indexss.ejs');
});
app.use('/', router);
app.post('/api/photo', function(req, res){
upload(req, res, function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
router.get('/download', function(req, res) {
var dir = path.resolve(".") + '/uploads/';
fs.readdir(dir, function(err, list) {
if (err)
return res.json(err);
else
res.json(list);
});
});
router.get('/download/:file(*)', function(req, res, next){
var file = req.params.file;
var path = require('path');
var path = path.resolve(".") + '/uploads/' + file;
res.download(path, file, function(err){
if (err){
console.log(err);
} else {
console.log('downloading successful');
}
});
});
app.listen(8080);
and here's the indexss.ejs file that contains the html and javascript
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>
<script>
$(document).ready(function() {
$('#uploadForm').submit(function() {
$("#status").empty().text("File is uploading...");
$(this).ajaxSubmit({
error: function(xhr) {
console.log(xhr);
status('Error: ' + xhr.status);
},
success: function(response) {
$("#status").empty().text(response);
console.log(response)
}
});
return false;
});
$.ajax({
url: "/download",
method: "get",
success: function(data){
downloadArray = data;
for (i = 0; i < downloadArray.length; i++){
console.log(downloadArray[i]);
console.log(typeof downloadArray[i]);
$('#downloadList').append("<a href='#' onclick='downloadFile(this)'>" + downloadArray[i] + "</a><br>");
}
}
});
});
function downloadFile(selectedFile){
fileToDownload = $(selectedFile).text();
console.log(fileToDownload);
$.ajax({
url: "/download/" + fileToDownload,
method: "get",
success: function(){
console.log('successful downloading');
}
});
}
</script>
</head>
<body>
<form id="uploadForm"
enctype="multipart/form-data"
action="/api/photo"
method="post">
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload" name="submit">
<input type='text' id='random' name='random'><br>
<span id = "status"></span>
</form>
<div id='downloadList'></div>
</body>
You're overriding path with filename parameter. Try this:
res.download(path);
And read res.download(path [, filename] [, fn]) at: https://expressjs.com/en/api.html
try the following code
server
var app = express();
var fs = require('fs');
app.get('/image', function (req, res) {
var path_image = req.headers.path;
var src = fs.createReadStream(path_image);
src.on('open', function () {
src.pipe(res);
log.info('down completed: ' + path_image);
});
src.on('error', function (err) {
log.error('' + err);
});
});
path_image is your file path, i use the client-side information sent
java-client use library https://github.com/koush/ion
Ion.with(MainActivity.this)
.load("http://IP:PORT/image")
.setHeader("path", path_image_on_server)
.progress(new ProgressCallback() {
#Override
public void onProgress(long downloaded, long total) {
Log.e("bc", "" + downloaded + " / " + total);
}
})
.write(new File(path_image_save_file))
.setCallback(new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File file) {
if (e != null) {
Log.e("bc", e.toString());
}
if (file != null) {
Log.e("bc", file.getAbsolutePath());
}
}
});

Return query data to render in ejs node js

I'm retrieving data from mysql db and I need to send data to render in my ejs file.
router.get('/', function(req, res, next) {
res.render('index', { speedAccelData: getSpeedAccelData() });
});
module.exports = router;
Following is the function which I used to get data from database. It successfully prints jsonStr with required data. I need to return jsonStr from the function.
var getSpeedAccelData = function () {
var jsonStr;
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "db_name"
});
con.connect(function(err){
if(err){
console.log('Error connecting to Db');
return;
}
});
con.query('SELECT * FROM table_name',function(err, result){
if(err) throw err;
jsonStr = JSON.stringify(result)
console.log(jsonStr);
});
con.end();
};
How can I return query data to render?
You can use Promise to achieve this
var getSpeedAccelData = function () {
var promise = new Promise(function (resolve, reject) {
var jsonStr;
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "db_name"
});
con.connect(function(err){
if(err){
console.log('Error connecting to Db');
reject();
}
});
con.query('SELECT * FROM table_name',function(err, result){
if(err) {
reject(err);
} else {
jsonStr = JSON.stringify(result)
resolve(jsonStr);
}
});
con.end();
});
return promise;
};
Then in your controller you can proceed like this :
router.get('/', function(req, res, next) {
getSpeedAccelData()
.then(function success(result) {
res.render('index', { speedAccelData: result });
}, function error(error) {
...
});
});

Categories

Resources