Is it possible to dynamically change the destination folder name depending on the field name? I made a quick test which failed
app.use(multer({
dest: './uploads/',
rename: function (fieldname, filename) {
if(fieldname == 'avatar_file'){
return filename.replace(/\W+/g, '-').toLowerCase() + Date.now()
} else {
return 'avatars/' + filename.replace(/\W+/g, '-').toLowerCase() + Date.now()
}
}
}))
Thanks
You can't. However, you can move the file to other locations after the file is uploaded.
@kokujin If you are still interested, I managed to do this with this small addition:
"rename" : function (fieldname, filename, req, res) {
return path.join(fieldname, "i" + req.params.user_id);
}
(Saves it like <defaultFolder>/<fieldName>/i564221sdd456.jpg. I added the "i" because some stuff might complain with filenames starting with numbers)
I got the idea after looking at multer's source code. It seems that it does a path.join() to get the full path using the destination folder and the uploaded filename. Adding this works for me.
Note that this might change in the future, breaking this code? @hacksparrow?
Actually is there a specific reason why fieldnames and filenames cannot be passed to changeDest()?
@Mindstormer619 I think that the problem with using fieldnames is that they might not be available when the file comes. Most browsers sends the fields and files in the order they are placed in the DOM. So if the field for the name is after the file input field, multer won't know about it when it's receiving the file.
Ohhh, interesting. So I'm taking it that the rename feature works after the file is done uploading?
Hmm, looking at the source it doesn't seem to be a problem to be including the field name as a param for the changeDest() function. I could be wrong about this. Can someone confirm?
@LinusU I'm fairly sure that multer is well aware of the fieldname before the file is uploaded, as can be referenced by file.fieldname within the onFileUploadStart function
@Mindstormer619 Ahh, I think I misunderstood. I thought the question was about renaming it to the value of another field. The fieldname is known to multer at that point, although not passed to the changeDest function.
Your workaround should work :+1:
@LinusU My workaround _does_ work :stuck_out_tongue: . However I'm asking about it being added directly to the source. Sort of like changing changeDest(dest, req, res) to changeDest(dest, req, res, fieldname).
This will be fixed by #131, specifically by #126 and #123
@Mindstormer619 : This does not seem to work for me, the upload occurs, but only to the default directory. Warning: nodejs noob.
var express = require('express');
var multer = require('multer');
var fs = require('fs');
//var upload = multer({ dest: 'uploads/' });
var app = express();
app.use(express.static(__dirname + "/public"));
app.post('/profile', multer({
dest: 'uploads/', rename: function(fieldname, filename, req, res){
var newDestination = path.join(req.body.hdnUserName);
return newDestination;
}}).single('uploadedFile'), function (req, res, next) {
res.end('over');
});
app.listen(8080, function(e){console.log('Server is listening on port 8080')});
rename should be sent to the storage, not multer.Try this:
var express = require('express')
var multer = require('multer')
var fs = require('fs')
var storage = multer.diskStorage({
destination: 'uploads/',
filename: function (req, file, cb) {
cb(null, req.body.hdnUserName)
}
})
var upload = multer({ storage: storage })
var app = express()
app.use(express.static(__dirname + "/public"))
app.post('/profile', upload.single('uploadedFile'), function (req, res, next) {
res.end('over')
})
app.listen(8080, function () {
console.log('Server is listening on port 8080')
})
@LinusU: Thanks for bringing up #188. This helped me get what i wanted thanks!
Why not just create a storage script that changes the directory dynamically ?
Example of code i use to achieve this .
var multer = require('multer'); // middleware for handling multipart/form-data,
// Constructor
module.exports = function (name) {
try {
// Configuring appropriate storage
var storage = multer.diskStorage({
// Absolute path
destination: function (req, file, callback) {
callback(null, './uploads/'+name);
},
// Match the field name in the request body
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
return storage;
} catch (ex) {
console.log("Error :\n"+ex);
}
}
@AndrewKralovec answers should be in the README.md file as an example
I think it would help a lot of people and help them to spend less time searching for this functionnality
Why not just create a storage script that changes the directory dynamically ?
Example of code i use to achieve this .var multer = require('multer'); // middleware for handling multipart/form-data, // Constructor module.exports = function (name) { try { // Configuring appropriate storage var storage = multer.diskStorage({ // Absolute path destination: function (req, file, callback) { callback(null, './uploads/'+name); }, // Match the field name in the request body filename: function (req, file, callback) { callback(null, file.fieldname + '-' + Date.now()); } }); return storage; } catch (ex) { console.log("Error :\n"+ex); } }
Thx so much!
___Arigato!
Why not just create a storage script that changes the directory dynamically ?
Example of code i use to achieve this .```
var multer = require('multer'); // middleware for handling multipart/form-data,
// Constructor
module.exports = function (name) {
try {
// Configuring appropriate storage
var storage = multer.diskStorage({
// Absolute path
destination: function (req, file, callback) {
callback(null, './uploads/'+name);
},
// Match the field name in the request body
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
return storage;
} catch (ex) {
console.log("Error :\n"+ex);
Can you explain me where to call this script
@kancharla-sandeep , sure thing. Please excuses the code quality, this project was from college, and it was before i even knew what a promise was.
https://github.com/AndrewKralovec/Alpha-Learning/search?q=storage&unscoped_q=storage
Dynamically changing destination folder name is done by using formidable and fs
var formidable = require('formidable');
var fs = require('fs');
var initial_path = "D:/Files/";
var path=""; //dynamically created path will be stored at runtime
new formidable.IncomingForm().parse(req)
.on('field', (name, field) => {
//field is an value of dynamic creation folder name
path = init_path+field+"/";
console.log(path); //Dynamic path is going to create
fs.mkdir(path, { recursive: true }, (err) => {
if (err) throw err;
});
})
.on('fileBegin',(name, file) => {
console.log(file.name);
var a = file.name;
var b = a.split('.');
var fname = b[0].replace(/\s/g, '');
file.path = path + fname+"."+b[1];
file_path = file.path;
savedImagePath = file_path.substring(1);
})
.on('file', (name, file) => {
console.log('Uploaded ' + file.name);
})
@prabhud9468 thanks for the solution, i was exactly looking for the similar kind of solution.
188 would probably have helped here. Your problem is that
renameshould be sent to the storage, not multer.Try this:
var express = require('express') var multer = require('multer') var fs = require('fs') var storage = multer.diskStorage({ destination: 'uploads/', filename: function (req, file, cb) { cb(null, req.body.hdnUserName) } }) var upload = multer({ storage: storage }) var app = express() app.use(express.static(__dirname + "/public")) app.post('/profile', upload.single('uploadedFile'), function (req, res, next) { res.end('over') }) app.listen(8080, function () { console.log('Server is listening on port 8080') })
Hi, I tried your snippet code, and well it does not even compile :
> [email protected] build /home/scrapbook/tutorial/pokus
> tsc -p src
src/controllers/file.controller.ts(37,62): error TS2339: Property 'body' does not exist on type 'Request'.
const pokusStorageOnDisk = multer.diskStorage({
destination: function(req, file, cb) {
// le r茅pertoire [workspace/pokus] doit exister
cb(null, 'workspace/pokus');
},
// By default, multer removes file extensions so let's add them back
filename: function(req, file, cb) {
console.log(" Valeur chopee : [" + file.fieldname + '-' + Date.now() + path.extname(file.originalname) + "]");
console.log(" Valeur file.originalname : [" + file.originalname + "]");
console.log(" Valeur file.path : [" + file.path + "]");
console.log(" Valeur path.extname(file.originalname) : [" + path.extname(file.originalname) + "]");
console.log(" Valeur req.body.hdnUserName : [" + req.body.hdnUserName + "]");
cb(null, file.originalname);
}
});
So maybe your code compiled once.
Most helpful comment
Why not just create a storage script that changes the directory dynamically ?
Example of code i use to achieve this .