Nodejs + Expressjs : Pass value in POST with Uploading of file - node.js

I am new in node. I just want to pass value in POST request with something like uploading of file. here is my sample code:
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var multer = require('multer');
var upload = multer({ dest: '/tmp/'});
app.use(express.static('public'));
app.post('/process_post', urlencodedParser, function (req, res) {
console.log(req.files.file.name);
var file = __dirname + "/" + req.files.file.name;
fs.readFile( req.files.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if( err ){
console.log( err );
}else{
response = {
message:'Save successfully',
first_name:req.body.firstname,
last_name:req.body.lastname,
filename:req.files.file.name
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
})
HTML:
<html>
<body>
<form action="http://127.0.0.1:8081/process_post" method="POST" enctype="multipart/form-data">
First Name: <input type="text" name="firstname">
<br>
Last Name: <input type="text" name="lastname">
<br>
Picture: <input type="file" name="file" size="50" />
<br>
<input type="submit" value="Submit">
</form>
</body></html>
The req.files is always undefine.
Thanks in advance!

You're requireing multer, but never configuring or using it. from the docs:
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})

Related

TypeError: Cannot read property 'name' of undefined node js

I have the file submission form on the index.html file. When the file selected, i need to say 'file uploaded', else need to display 'please upload the file'
app.js
const express = require("express");
const app = express();
const http = require("http").Server(app).listen(3000);
app.use(express.urlencoded());
app.use(express.json());
console.log("Server Started");
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
}
)
app.post("/", function (req, res) {
if (req.files) {
console.log(req.files);
const file = req.files.filename;
const filename = file.name;
if (!filename) {
res.send("Please select the file to upload");
}
else {
res.send("uploaded");
}
}
})
index.html
<div>
<h1 style="align-content: center">Upload your file here!</h1>
</div>
<div >
<form label="upload" method="post" enctype="multipart/form-data" action="/">
<label> Enter reference</label>
<input type="text" name="test_text"></input>
<br><br>
<input type="file" name="filename">
<input type="submit" value="upload">
</form>
</div>
Error message:
TypeError: Cannot read property 'name' of undefined
at C:\Users\Desktop\LocalGithub\uploadFileLocal-express-fileupload\app.js:24:27
The following is quoted from express docs:
In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.
As it said, I suggest you to use multer since it's more popular and easy to use
EDIT:
If you are using "express-fileupload" middleware, you have to load it via .use() method:
const express = require("express");
const app = express();
const http = require("http").Server(app).listen(3000);
const fileUpload = require('express-fileupload');
^^^^^
app.use(express.urlencoded());
app.use(express.json());
app.use(fileUpload({
^^^
useTempFiles : true,
tempFileDir : '/tmp/'
}));
...
check the docs for more details:
Please try replace file.name with req.files[0].originalname.
You did not create the object for which attribute name is defined.
object: req.files.filename, attribute: req.files.filename.name should work fine.
Your code should be like this:
app.post("/", function (req, res) {
if (req.files.filename) { //missing filename
console.log(req.files.filename); //missing filename
const file = req.files.filename;
const filename = file.name;
...
});

Show Image file using NodeJS

Using node.js and mongodb I want to upload image and show that image using it's id.
but When i run it, showing an error..
Error: Failed to lookup view "/showImage" in views directory "H:\NodeJS\AddImage
\views"
searching a lot but couldn't find any proper and working solution for me.
what's the problem??
can anyone help??
thanks..
here is my code...........
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
var multer = require('multer');
app.use(bodyParser.json());
app.use(express.static('public'));
var imagefile = require('./routes/imagefile');
app.set('view engine', 'ejs');
mongoose.connect('mongodb:..url');
imagefile(app);
app.listen(3000);
console.log('Running on port 3000');
imagefile.js
var express = require('express');
var multer = require('multer');
var mongoose = require('mongoose');
var fs = require('fs');
var imageSchema = mongoose.Schema({
img: { data: Buffer, contentType: String },
imageName : String
});
var Item = mongoose.model('Clothes',imageSchema);
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'public/')
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({
storage: storage
});
module.exports = function (app) {
app.get('/', function(req, res, next) {
res.render('index.ejs');
});
app.get('/images/:id', function(req, res) {
Item.findById(req.params.id, function (error, result) {
//res.contentType(result.contentType);
console.log(result.imageName);
//res.end(result.image.buffer, "binary");
res.render('/showImage',{imageName : result.imageName, imageId : result.imageName});
});
});
app.post('/', upload.any(), function(req, res, next) {
var newItem = new Item();
newItem.img.data = fs.readFileSync(req.files[0].path)
newItem.img.contentType = 'image/png';
newItem.imageName = req.files[0].originalname;
newItem.save();
res.render('index.ejs');
});
};
index.ejs
<html>
<head>
<title>test</title>
</head>
<body>
<form action "/" method="POST" enctype="multipart/form-data">
<input type="file" name="myimage" ></input>
<input type="submit" name="submit" value="submit"></input>
</form>
</body>
</html>
showImage.ejs
<html>
<head>
<title>test</title>
</head>
<body>
<h1><%= imageName %></h1>
<h1><%= imageId %></h1>
<div class="header">
<img src='/public/36417514_2140268509321308_7450232816341614592_n.jpg %>' />
</div>
</body>
</html>
Remove the leading slash in this function:
app.get('/images/:id', function(req, res) {
// Rest of the code
// ...
res.render('showImage', // <-- Remove slash
{imageName : result.imageName, imageId : result.imageName});
});
});
the problem is that it looks for file named '/showImage.ejs'.

Multer is not populating req.body and req.file

I am using Multer to parse a multipart form in a keystone environment and and not able to access the req.body and req.file data inside my route controller
routes/index.js
var keystone = require('keystone'),
middleware = require('./middleware');
var bodyParser = require('body-parser');
//multi-part form parser for FTP api
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({storage: storage});
exports = module.exports = function(app) {
app.use(bodyParser.json({limit: '10mb'}));
app.use(bodyParser.urlencoded({limit: '10mb', extended: true}));
app.post('/upload_api', upload.single('formFile'), routes.api.uploadFTP);
};
routes/api/uploadFTP.js
var keystone = require('keystone');
var ftpMod = require('ftp');
var fs = require('fs');
exports = module.exports = function(req, res) {
console.log("req.body is ");
console.log(req.body);
console.log("req.file is ");
console.log(req.file);
res.send("console.log() outputted to screen");
}
public/test-upload.html
<html>
<body>
<form name="sampleForm" enctype="multipart/form-data" action="/upload_api" method="post">
<p>Method</p>
<input type="text" name="method"><br>
<p>Options</p>
<input type="text" name="options"><br>
<p>File</p>
<input type="file" name="formFile"><br><br>
<input type="submit" value="Click to Send">
</form>
</body>
</html>
The response i receive from nodejs is
>req.body is
{}
req.file is
undefined
I am expecting req.body to contain {method: "sometext"}
and req.file to be populated
You can not get values in either req.body or req.file. Replace youe uploadFTP.js with below given code.
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, <<path where you want to store your files>>);
},
filename: function(req, file, callback) {
callback(null, path.basename(Date.now() + '_' + file.originalname));
},
});
var maxSize = 1024 * 1024;
var upload = multer({
storage: storage,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.gif' && ext !== '.jpeg') {
return callback(res.status(202).end();, null);
}
callback(null, true);
},
limits: {fileSize: maxSize},
}).single('image');
exports = module.exports = function (req, res) {
upload(req, res, function(err) {
console.log(storage.diskStorage);
if(err) {
return res.status(201).end();
}
//Do stuff here
res.status(200).end();
});
}
Replace below line in index.js
app.post('/upload_api', upload.single('formFile'), routes.api.uploadFTP);
with
app.post('/upload_api', routes.api.uploadFTP);

How can I show a progress bar of the file upload in my html

I have a file upload in node js. I want to show a line displaying upload started / upload failed / upload completed and a graphic progress bar.
How can I implement this?
Node.js:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './upload');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).array('file', 3);
router.get('/', function(req, res){
res.send( {success: 'File uploaded!'});
})
router.post('/upload', function(req,res){
upload(req,res,function(err) {
console.log('Selected Files: ', req.files);
if(err){
res.end("Error: '" , err , "'");
}else{
console.log('Files uploaded!');
res.sendStatus(204);
}
});
});
module.exports = router;
HTML
<form enctype = "multipart/form-data"
action = "/upload"
method = "POST"
>
<input type="file" name="file"/>
<p></p>
<input type="file" name="file"/>
<p></p>
<input type="submit" value="Upload File" name="submit">
</form>
<p id="success">{{success}}</p>
Use XMLHttpRequest and .addEventListener("progress") on the client side to submit the form

node.js multi file upload not working

<form action="http://localhost:3000/examples" method="post" enctype="multipart/form-data" accept="application/json">
<input type="text" name ="name">
<input type="text" name ="codedescription">
<input type="file" name ="file">
<input type="submit" value="Upload selected file to server">
</form>
var multer = require('multer');
app.use(multer({ dest: './uploads/',
onFileUploadStart : function(file){
console.log('File recieved:');
console.log(file);
},
onFileUploadData:function (file,data){
console.log('Data recieved');
},
onParseEnd: function(req,next){
next();
}
}));
app.route('/examples').post(users.requiresLogin, examples.create);
exports.create = function(req, res) {
console.log("req.files"+req.files);
console.log("req.name"+req.body.name);
console.log("req.codedescription"+req.body.codedescription);
};
Submit form without enctype="multipart/form-data" is working but I can not get files.
Submit form with enctype="multipart/form-data" is working but I can not get files as well as data.
you can try this
<html>
<head>
<title>FileUpload</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "http://localhost:3000/api/photo"
method = "post"
>
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload Image" name="submit" id="btnUpload">
<span id="spnStatus" />
</form>
<script>
$(document).ready(function(){
$('#btnUpload').click(function(){
$('#spnStatus').empty().text("File is Uploading");
$(this).ajaxSubmit({
error : function(xhr){
status('Error : '+xhr.status);
}
success : function(response){
$('#spnStatus').empty().text(xhr);
}
});
});
});
</script>
</body>
</html>
NodeJS Express
var express = require("../node_modules/express");
var multer = require('../node_modules/multer');
var bodyParser = require("../node_modules/body-parser");
var app = express();
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());
}
});
var upload = multer({ storage : storage }).array('userPhoto',8);
app.get('/',function(req,res){
res.sendFile(__dirname + "/fileUpload.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
console.log(err);
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.listen(3001,function(){
console.log("Working on port 3001");
});
Now you can upload upto 8 files at a time, if you want to upload more than eight, just edit var upload = multer({ storage : storage }).array('userPhoto','LIMITHERE');
#karthik comment, i think you need this as well including after jquery, when you want to use his example:
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>

Resources