Express js Image upload and Text inputs using post method - node.js

I have following code for uploading image and handling text input. But both are not working together
*Images are uploading properly but I can't get text field value *
var express = require('express');
var multer = require('multer');
var mime = require('mime');
var app = express();
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + '.' + mime.extension(file.mimetype));
}
});
var upload = multer({ storage : storage }).array('userPic');
app.get('/completeForm.html', function(req, res){
res.sendFile(__dirname + '/' + 'completeForm.html')
});
app.post("/postFormAct", function (req, res, next) {
console.log(req.body.user); // Here i getting undefined
console.log(req.body.email);// Here i getting undefined
upload(req,res,function(err) {
console.log(req.files); // Here i getting proper output and image also uploading to concern folder
});
});
app.listen(3000);
Html code given below.... please help me someone
<form method="post" action="/postFormAct" enctype="multipart/form-data">
<input type="text" name="user"><br>
<input type="text" name="email"><br>
<input type="file" name="userPic"><br>
<input type="submit" value="Submit">
</form>

Just put
console.log(req.body.user);
console.log(req.body.email);
inside your upload function. After the function may also work.

That's because there is no multipart/form-data parsing middleware called before your /postFormAct route handler.
You have two parsing middlewares set up but not one of them parse this multipart/form-data Content-Type.
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Multer does that, so you can access req.body.user and req.body.email variables in handlers following your upload middleware.

Related

Multer nodejs - req.file is undefined

I am creating an app using Node, Express and ejs and multer for uploading images. Every time I submit the form, req.file is undefined. I've spent the entire day troubleshooting but can't figure out what I'm doing wrong.
HTML
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required>
<input class="submit" type="submit" value="Post" />
</form>
app.js
const path = require('path');
const express = require('express');
const morgan = require('morgan');
const bodyParser = require("body-parser");
const multer = require('multer');
const app = express();
app.use(express.static(path.join(__dirname, 'public')))
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname,'resources/views'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
app.post("/post", upload.single("image"), (req, res) => {
console.log(req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(, () => {
console.log(`Example app listening at http://localhost:3000/login`);
});
You have few little bugs: first you forgot to add port and instead of login it should be post then we hit the correct address immediately, avoiding error Cannot GET /login
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
Project Folder & File structure:
app.js I added simple an error handler to the:
app.post("/post", upload.single("image"), (req, res, next) => {}
const path = require("path");
const express = require("express");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const multer = require("multer");
const app = express();
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "resources/views"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
// app.post("/post", upload.single("image"), (req, res) => {
// console.log(req.file);
// });
app.post("/post", upload.single("image"), (req, res, next) => {
const file = req.file;
if (!file) {
const error = new Error("Please upload a file");
error.httpStatusCode = 400;
return next(error);
}
res.send(file);
console.log("Success", req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
post.ejs
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required />
<input class="submit" type="submit" value="Upload File" />
</form>
output:
after selecting the file and pressing upload file:
VSCode output:
Works like a charm ;-)

why unable to display value of title?

I am trying to output the value of title which i entered in the form in the /Add-Product link
Here is my app.js code
const http= require('http');
const path= require('path');
const express= require('express');
const app= express();
app.set('view engine', 'ejs');
app.set('views', 'Views');
app.use(express.static(path.join(__dirname, 'Public')));
app.get('/', (req, res, next)=>{
res.render('shop');
});
app.get('/admin', (req, res, next)=>{
res.render('admin');
});
app.get('/add-product', (req, res, next)=>{
res.render('addProduct');
});
app.post('/add-product', (req, res, next)=>{
console.log(req.body.title); //uable to display value of req.body.title
res.redirect('/');
});
app.listen(3000);
form part of the addProduct.ejs
<main>
<form action="/add-product" method="POST">
<p>Title</p>
<input type="text" name="title" id="title"/>
<p>Price</p>
<input type="text" name="price"/>
<p>Description</p>
<input type="text" name="description"/>
<button type="submit">Submit</button>
</form>
</main>
Unable to figure why the req.body.title is throwing an error as:Cannot read property 'title' of undefined
Please guide me on what i am missing.
By default, form submits the data to server in the content type of application/x-www-form-urlencoded. So you need to configure node js to receive this type of content. Use bodyParser to read the request body with json and encoded content.
Usage:
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true }));

What is the reason req.body is displayed as undefined?

Hi i am making a blog with node js. And now I am implementing the function to write a post, but there is a problem in this process.
new.ejs is a screen for creating a post.
new.ejs
<div>
<h2> new post </h2>
<form action="/articles" method = "POST">
<h4>title</h4>
<input required type="text" name = "title" / class='form-control'><br>
<h4>description</h4>
<textarea name="description" class = 'form-control'></textarea><br>
<h4>contents</h4>
<textarea id="mytextarea" name="contents" rows = '10'></textarea>
취소<button type = "submit" class="btn btn-primary">저장</button>
</form>
</div>
and
article.js
var express = require("express");
var app = express();
var router = express.Router();
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
router.get("/", function (req, res) {
res.send("article");
});
router.get("/new/home", function (req, res) {
res.render("articles/index");
});
router.get("/new", function (req, res) {
res.render("articles/new");
});
router.post("/", function (req, res) {
console.log(req.body.title);
});
module.exports = router;
Here, when req.body.title is executed, req.body becomes undefined. And in the code editor window, a sentence stating that bordyParser has been deprecated appears as the middle line is drawn. How to solve it
The EJS file is POSTing to /articles, but your POST route in the NodeJS is /.
To fix the 'body-parser is deprecated' messages, change the code as follows :-
...
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
...
to
...
app.use(express.urlencoded());
...
Body Parser is now part of Express itself.

Node.JS + Express parse CSV file on server

Essentially, what I have is a form where a user will upload a CSV file.
<form action="/upload" method="POST" enctype="multipart/form-data">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile" name="file" required>
<label class="custom-file-label" for="customFile">Choose file</label>
</div>
<input type="submit" class="btn btn-primary btn-block">
</form>
FYI: I'm using getbootstrap.com as my style sheet.
Now, the form sends a POST request to /upload which is where my node.js code is. What I need is for the server to parse this CSV file and extract the data. I've got no idea what to do as all the different NPM packages such as Multer are using a system where the save the file locally and then parse it.
Edit: Forgot to mention this, but temporary local CSV hosting is not an option.
I need the client to upload server to process it and push to a DB, can't save the file locally anywhere.
Edit 2: I've used multer and the memory processing option and have gotten the following.
const express = require("express");
const app = express();
var bodyParser = require("body-parser");
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", function(req, res) {
response.sendFile(__dirname + "/views/index.html");
});
app.post("/upload", upload.single('file'), async (req, res) => {
res.send(req.file)
});
const listener = app.listen(process.env.PORT, function() {
console.log("Your app is listening on port " + listener.address().port);
});
Now once I upload the file, I'm getting the following response (this is what req.file is).
{"fieldname":"file","originalname":"tech.csv","encoding":"7bit","mimetype":"application/octet-stream","buffer":{"type":"Buffer","data":[67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101]},"size":56}
So It's pretty clear that our data happens to be
67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101
but how do I process that? The csv file data was
CLASS ID,TECH #,FIRST NAME,LAST NAME
6O,6O01,Anish,Anne
So how do I go from the information provided in the buffer data attribute to the actual data?
All you have to use is Multer. Multer will return a buffer object which you can then make a string with the .toString() attribute.
Code:
const express = require("express");
const app = express();
var bodyParser = require("body-parser");
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", function(request, response) {
response.sendFile(__dirname + "/views/index.html");
});
app.post("/upload", upload.single('file'), async (req, res) => {
var b = req.file["buffer"]
console.log(b.toString())
res.send(b.toString())
});
const listener = app.listen(process.env.PORT, function() {
console.log("Your app is listening on port " + listener.address().port);
});

Express body-parser request.body returning undefined

when i run this app and submit the form 'console.log(request.body)' returning undefined. i am a beginner in node js . can anyone please explain what i am doing wrong?
this is the registration form
register.jade
doctype html
html
head
title.
Fonebook
link(rel='stylesheet', href='/assets/bootstrap/css/bootstrap.min.css')
script(src='https://code.jquery.com/jquery-2.2.0.min.js')
script(src='/assets/bootstrap/js/bootstrap.min.js')
body
div.container
h3.
The Fonebook
form(method="POST",class="center",id="regForm",action='/doReg',enctype="multipart/form-data")
div.panel.panel-info
div.panel-heading.
Registration
div.panel-body
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Profile Picture:
input(type='file',name='proPic')
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Email:
input.form-control(id="email", type="email", name="email", placeholder="Enter email ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Name:
input.form-control(id="name", type="text", name="name", placeholder="Enter name ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Password:
input.form-control(id="password", type="password", name="password")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
a(href='login').
Already have an account?
div.panel-footer
button.btn.btn-info(type="submit").
Register
here is my app.js file
var express = require('express');
var app = express();
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1/test');
var uploadDir = __dirname + '/uploads';
var fs = require('fs');
var multer = require('multer');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var conn = mongoose.connection;
app.set('views', './views');
app.set('view engine', 'jade');
app.use('/assets', express.static(__dirname + '/public'));
var port = process.env.PORT || 3000;
app.all('/', function (req, res) {
res.render('login');
})
app.all('/register', function (req, res) {
res.render('register');
})
app.all('/login', function (req, res) {
res.render('login');
})
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, uploadDir);
},
filename: function (request, file, callback) {
//console.log(file);
callback(null, Date.now() + '.jpg');
}
});
var upload = multer({storage: storage}).single('proPic');
app.all('/doReg', function (request, response) {
upload(request, response, function (err) {
if (err) {
console.log(err);
return;
}
//console.log(request.file);
response.end('Your File Uploaded');
})
console.log(request.body);
});
app.listen(port);
body-parser does not support multipart forms.
From their README
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:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
Seeing as you're already using multer you can access your fields this way:
app.all('/doReg', upload, function (request, response) {
console.log(request.body);
});

Resources