Multer 'storage' option does not work while 'dest' one does - node.js

I'm using Multer to upload and store files. If I use the dest option files upload to my /uploads folder with no problem. Whilst this works, it's saving the uploads like 2eb3f1a6def453f7a461c5de353b06f8 so I want to use the storage option, but for some reason this doesn't work or me and the files upload (logged in console), but wont save to the folder.
I've tried a few different ways of achieving this and none work. Can anyone point out what might be wrong?
{
fieldname: 'attachments',
originalname: 'myFile.pdf',
encoding: '7bit',
mimetype: 'application/pdf',
destination: 'uploads/',
filename: '2eb3f1a6def453f7a461c5de353b06f8',
path: 'uploads/2eb3f1a6def453f7a461c5de353b06f8',
size: 57638
}
const express = require('express');
const app = express();
const multer = require("multer");
const path = require('path');
// const upload = multer({ dest: "uploads/" }); // this works, file saves to /uploads
var upload = multer({ storage: storage }); // this doesnt work/ files dont save to /uploads
// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
var storage = multer.diskStorage({
destination: function(req, file, cb) {
// cb(null, 'uploads/');
// cb(null, __dirname + '/uploads');
cb(null, './uploads');
},
filename: function (req, file, cb) {
// cb(null , file.originalname);
// cb(null, file.fieldname + '-' + Date.now());
// By default, multer removes file extensions so let's add them back
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
// var upload = multer({ storage: storage });
app.post('/', upload.array('attachments') , (req, res) =>{
try {
res.send(req.files);
console.log('body', req.body);
console.log('files', req.files);
} catch(error) {
console.log(error);
res.send(400);
}
});
module.exports = {
path: '/api/upload',
handler: app
};

Declaring var upload = multer({ storage: storage }) after having it defined with multer.diskStorage was enough to fix OP's issue.

Related

Multer Doesn't Save Images in Local Folder

Multer cannot store the file, where the destination is in public/my-uploads
const express = require('express');
const app = express();
const multer = require('multer');
let storage = multer.diskStorage({
destination: '/public/my-uploads',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
const upload = multer({dest:'storage/'}).single('file');
app.post('/upload', upload, (req , res) => {
console.log(req.files) // this does log the uploaded image data.
})
Try this File Storage For Save image in Local
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "images");
},
filename: (req, file, cb) => {
cb(
null,
new Date().toISOString().replace(/:/g, "-") + "-" + file.originalname
);
},
});
This happens because you are using windowsOS and where you learned it may be using macOS in windows Path have to setted as mentioned in the above code.
You simply set the file name as given in my answer and destination is root dir "./images"...

nodejs multer is getting req.file but not uploading it to destination

multer.js
var path = require("path"),
multer = require("multer");
const storage = multer.diskStorage({
destination: function(req, file, next){
next(null, '../public/imgs/');
return;
},
filename: function(req, file, cb){
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
});
module.exports = upload;
router.js
//handle createPartner route
router.post("/partner/new", upload.single('image'), function(req, res){
console.log(req.file);
console.log(req.body);
req.body.Partner["image"] ="/static/imgs/"+req.file.filename;
req.body.Partner.body = req.sanitize(req.body.Partner.body);
Partner.create(req.body.Partner, function(err, createdPartner){
if(err){
console.log(err);
res.redirect("/admin/partner/new");
}else{
res.redirect("/partners");
}
});
});
I get the following console.log
{ fieldname: 'image',
originalname: 'fb.png',
encoding: '7bit',
mimetype: 'image/png',
destination: '../public/imgs/',
filename: 'image-1521727739861.png',
path: '../public/imgs/image-1521727739861.png',
size: 21532 }
{ Partner: { name: 'test', bio: 'test', image: '', website: 'test' } }
so multer does get the file but it doesn't upload it to the destination! The permissions for /public and /public/imgs are 777. Everywhere I searched uses the other method for multer but that way I'll have to specify (single/multiple/any) in advance which isn't right.
You need to include the absolute path as I mentioned in comments.
You can easily do this by utilising path.join like follows:
var path = require('path');
var dir = path.join(__dirname, '../public/imgs')
That will concatenate __dirname which is the absolute path of the current file with your images file.

Set Upload Directory dynamically when uploading a file in NodeJs

I am a novice at NodeJS and I created a service to upload images to a shared location. However, I need to set the upload folder dynamically based on the user id: for e.g. the folder will be /uploads/{userid}/file.txt
I am not sure how to do it and I have been searching today with no luck.
The NodeJS service looks like:
var express = require('express')
var multer = require('multer')
var Storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./Uploads");
},
filename: function (req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" +
file.originalname);
}
});
var upload = multer({ Storage: Storage })
var app = express()
app.post('/upload', upload.array('uploads[]', 12), function (req, res, next)
{
return res.end("Files uploaded sucessfully!.");
})
Thank you for the help.
Try this
app.use(multer({
dest: './uploads/',
"rename" : function (fieldname, filename, req, res) {
return path.join(fieldname, req.params.user_id+".txt");
}
})

Accesing filenames in req.files created by Multer, doing stuff to newly uploaded files

I'm new to web development. I have a multi-file upload on a page. The files are successfully uploaded with multer into my 'public/uploads' folder.
How do I access the filenames that I just uploaded using the req.files that multer creates? The result is not an array, although the multer docs say for multiple files, req.files will contain an array.
I feel like I have something set up incorrectly.
Here's console.log(req.files). as you can see the backets are not comma separated.
[ { fieldname: 'file',
originalname: 'acschemrev5b00690.jpeg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'public/uploads',
filename: '1484769679031-acschemrev5b00690.jpeg',
path: 'public/uploads/1484769679031-acschemrev5b00690.jpeg',
size: 79299 } ]
[ { fieldname: 'file',
originalname: 'acschemrev5b00701.jpeg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'public/uploads',
filename: '1484769679047-acschemrev5b00701.jpeg',
path: 'public/uploads/1484769679047-acschemrev5b00701.jpeg',
size: 127608 } ]
[ { fieldname: 'file',
originalname: 'acschemrev5b00703.jpeg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'public/uploads',
filename: '1484769679109-acschemrev5b00703.jpeg',
path: 'public/uploads/1484769679109-acschemrev5b00703.jpeg',
size: 117312 } ]
Here's my server app.js file:
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
// var upload = multer({ dest: 'uploads/' });
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads')
},
filename: function (req, file, cb) {
// cb(null, file.fieldname + '-' + Date.now());
cb(null, Date.now() + "-" + file.originalname);
// cb(null, file.originalname);
}
});
var upload = multer({ storage: storage });
// set the view engine to pug
app.set('view engine', 'pug');
app.use(express.static(__dirname + '/public'));
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.get('/', function (req, res) {
res.render('index');
});
// from multer
app.post( '/file-upload', upload.any(), function( req, res, next ) {
// Metadata about the uploaded file can now be found in req.file
res.send(req.files);
// console.log(req.files);
currentFiles = req.files;
console.log(req.files);
app.post('/crop-images')
});
I need to process the files that I just uploaded. What is the best way to do this? Do I need to create an array of each filename and then process each one? How do I get their names out of req.files?
Thanks!
If you want to retrieve filenames from the req.files, you could just map that over it like that:
var filenames = req.files.map(function(file) {
return file.filename; // or file.originalname
});
For those using Typescript, it will show errors if mapping over req.files. To overcome this, you can use the below:
(req.files as Array<Express.Multer.File>).map(...)
or
(req.files as Express.Multer.File[]).map(...)
For typescript, this worked for me.
const filenames = req.files! as Array<Express.Multer.File>
const file_names = filenames.map(file => file.filename)

Node/Multer Get Filename

I am using the following to upload files to a directory via Multer. It works great, but I need to perform some actions after upload that require the name of the file I just posted to the "upload" directory. How do I get the name of the file I just posted?
// Multer storage options
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'upload/');
},
filename: function(req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '.pdf');
}
});
var upload = multer({ storage: storage });
app.post('/multer', upload.single('file'), function(req, res) {
// Need full filename created here
});
var express=require("express");
var app=express();
var multer=require("multer");
var upload=multer({dest:"uploads/"});
app.post("/multer", upload.single("file"), function(req,res){
console.log(req.file.filename);
});
request.file gives the following stats, from which you would just need to pick request.file.originalname or request.file.filename to get the new filename created by nodejs app.
{
fieldname: 'songUpload',
originalname: '04. Stairway To Heaven - Led Zeppelin.mp3',
encoding: '7bit',
mimetype: 'audio/mp3',
destination: './uploads',
filename: 'songUpload-1476677312011',
path: 'uploads/songUpload-1476677312011',
size: 14058414
}
Eg, in nodejs express mvc app with ecma-6,
var Express = require('express');
var app = Express();
var multipartUpload = Multer({storage: Multer.diskStorage({
destination: function (req, file, callback) { callback(null, './uploads');},
filename: function (req, file, callback) { callback(null, file.fieldname + '-' + Date.now());}})
}).single('songUpload');
app.post('/artists', multipartUpload, (req, resp) => {
val originalFileName = req.file.originalname
console.log(originalFileName)
}
Accessing uploaded files data differs in Multer, depending whether you are uploading single or multiple files. Access data like so:
uploading single file:
req.file
uploading multiple files:
req.files
I found the answer on github, you have access to it in
res.req.file.filename
See there for more informations https://github.com/expressjs/multer/issues/302
app.post('/multer', upload.single('file'), function(req, res) {
// Need full filename created here
const file = req.file
if (!file) {
const error = new Error('Please upload a file')
error.httpStatusCode = 400
return next(error)
}
res.send(file) #Here
});
You need recover file from this line
res.send(file)
using file.filename
This output sample
{
"fieldname": "myFile",
"originalname": "isc te esta esperando.jpg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "uploads",
"filename": "myFile-1602293858948.eaf",
"path": "uploads/myFile-1602293858948.eaf",
"size": 297720
}
using
request.file.filename
fieldname Field name specified in the form
originalname Name of the file on the user's computer
encoding Encoding type of the file
mimetype Mime type of the file
size Size of the file in bytes

Resources