Multer is not populating req.body and req.file - node.js

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);

Related

Getting TypeError: Cannot read property 'content-length' of undefined When Using Node.js Formidable

I'm trying to console.log a number I type in an input using formidable. I am getting an error that says TypeError: Cannot read property 'content-length' of undefined. I have tried to add a fs.readFile into the code and it won't work.
Here is my app.js
const express = require('express');
const http = require('http');
const formidable = require('formidable');
const fs = require('fs');
const ejs = require('ejs');
const path = require('path');
const multer = require('multer');
const upload = multer({ dest: 'upload/'});
const type = upload.fields([{ name: 'gradeNumber', maxCount: 10 }]);
const app = express();
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.get('/fileupload', function (req, res) {
res.render("upload")
});
app.post('/fileupload', function (req, res) {
const form = new formidable.IncomingForm();
form.parse(function (err, fields, files) {
console.log(fields.gradeNumber);
const oldpath = files.filetoupload.path;
const newpath = 'C:/Users/Shubh Computer/Desktop/VSCode/Grades/1/' + files.filetoupload.name;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
});
});
app.listen(3000);
upload.ejs
<!DOCTYPE html>
<html>
<head>
<title>Upload File</title>
</head>
<body>
<form action="fileupload" method="post" enctype="multipart/form-data">
<input type="file" name="filetoupload"><br>
<label>What Grade</label><input type="text" name="gradeNumber"><br>
<input type="submit">
</form>
</body>
</html>
I'm trying to log the input with the name "gradeNumber". If somebody could help me I will be very grateful because I've gotten very frustrated with this.
"req" parameter in form.parse() method is omitted.
(method) IncomingForm.parse(req: IncomingMessage, callback?: (err: any, fields: Fields, files: Files) => any): void
Try changing the code as below.
app.post('/fileupload', function (req, res) {
const form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log(fields.gradeNumber);
const oldpath = files.filetoupload.path;
const newpath = 'C:/Users/Shubh Computer/Desktop/VSCode/Grades/1/' + files.filetoupload.name;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
});
});

How to upload a file in node.js server using multer

I'm trying to pass a file from my Angular app to a node.js server.
When I run the app, I get the following error:
Error: Please choose files
HTML:
<upload name="fileUpload" formControlName="fileUpload" #fileUpload (listChange)="updateList($event)" data-kind="primary"
[imagePreview]="true">
</upload>
Here is my updateList() method:
updateList(list: any) {
this.demolist = Array.apply(this, list);
this.attachmentReady.emit(this.demolist);
}
Node:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const multer = require('multer');
let nodemailer = require('nodemailer');
let aws = require('aws-sdk');
const fs = require('fs');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
});
var upload = multer({ storage: storage });
app.post('/postData', upload.array('fileUpload', 12), (req, res, next) => {
console.log(req.body);
res.json(req.body);
const files = req.files
if (!files) {
const error = new Error('Please choose files')
error.httpStatusCode = 400
return next(error)
}
res.send(files);
}
In a different project, multer is working as expected. Below is the HTML from that project:
<form action="/uploadmultiple" enctype="multipart/form-data" method="POST">
Select images: <input type="file" name="myFiles" multiple>
<input type="submit" value="Upload your files" />
</form>
The difference between my working code & the code that isn't working is that I'm able to use a standard input control if the type is file.
But I need to use an upload control now & my code isn't working when I make that one change.
Can someone please tell me how I can use this control to pass the file? Thanks a lot in advance!
After you have installed multer using npm install --save multer
Basic usage example:
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.post('/uploadmultiple', upload.single('myFiles'), function (req, res, next) {
// req.file is the `myFiles ` file
// req.body will hold the text fields, if there were any
})
app.post('/uploadmultiple', upload.array('myFiles', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
For more information you can read documentation here

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'.

Nodejs + Expressjs : Pass value in POST with Uploading of file

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
})

Node.js - expressjs - multer req.files outputs empty

i'm using multer to get a file from this form
<form action="/api/pimage" method="POST" enctype="multipart/form-data">
<fieldset>
<input type="file" name="profileimage">
<input type="submit">
</fieldset>
</form>
using this serverside script
app.post('/api/pimage', function(req, res, next) {
console.log(req.body, req.files);
});
the problem is that req.body is printing out { profileimage: 'image.png' }
and req.files is printing out {}
where you see the problem?
thanks
P.S. i'm using app.use(bodyParser.urlencoded({ extended: false })); to get req.body and app.use(multer({ dest: './uploads/'})); for req.files
I found that using multer alongside bodyParser can cause req.file to be undefined. Make sure to check that also if you're having issues.
I put MY (there are many I imagine and surely better) solution to help many people like me because I have searched during 1 entire day ;-(
var express = require('express');
var fileUpload = require('express-fileupload');
var fs = require("fs");
var app = express();
console.log('étape 0');
app.use(express.static('mesStatic'));
app.use(fileUpload());
console.log('étape 1');
app.get('/indexFileUpload.htm', function (req, res) {
res.sendFile( __dirname + "/" + "indexFileUpload.htm" );
})
console.log('étape 2');
app.post('/file_upload', function (req, res) {
console.log('étape 3');
console.log('req.files:' , req.files);
if (!req.files) {
res.send('No files to upload.');
return;
}
console.log('req.files.file.data:' , req.files.file.data);
var bufDataFile = new Buffer(req.files.file.data, "utf-8");
console.log('étape 3.1');
console.log('__dirname : ' + __dirname);
fs.writeFile(__dirname + '/file_upload/output.txt', bufDataFile, function(err) {
if (err) {
return console.error(err);
}
else {
console.log("Data written successfully !");
}
console.log('étape 4');
res.end('Fin OK !!!');
})
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port);
})
You have to provide your upload function defined for multer before asking for req.file in function(req, res), you can follow the code given below
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./images/");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: Storage }).single('imagePath');
router.post('/file_upload', upload, function(req, res, next){
console.log(req.file);
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./public/images/");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
var upload = multer({ storage: Storage }).single('imagePath');
router.post('/add-product', upload, function(req, res, next){
var newProduct = new Product();
}

Resources