multiple file upload not working with formidable in node js - node.js

app.post('/upload', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
try{
if (files.file.name != '') {
file_newname = dt.MD5(files.file.name + Date() + Math.random()) + '.jpg' + ;
var file_newpath = './tmp/' + file_newname;
fs.readFile(file_oldpath, function (err, data) {
// Write the file
fs.writeFile(file_newpath, data, function (err) {
console.log('File written!');
res.end(JSON.stringify({
message: 'file uploaded successfully'
}));
});
});
}
}catch (e) {
}
});
});
The single image upload is working perfectly.I tried the following code
var form = new formidable.IncomingForm();
files = [],
fields = [];
form.on('field', function(field, value) {
fields.push([field, value]);
})
form.on('file', function(field, file) {
console.log(file.name);
files.push([field, file]);
})
form.on('end', function() {
console.log('done');
//res.redirect('/forms');
});
form.parse(req);
But only a single image gets uploaded. i m using react in frontend. Node and express in backend.
I also tried multer. But that doesnt working
app.post('/getrast', upload.array('files'), function (req, res) {
res.json({data: req.files});
});

Use the multiple flag with the incoming form with true as value.
var form = new formidable.IncomingForm();
form.multiples = true; //use this while dealing with multiple files
files = [],
fields = [];
form.on('field', function(field, value) {
fields.push([field, value]);
})
form.on('file', function(field, file) {
fs.rename('add your logic here for renaming files'); // rename it here
console.log(file.name);
files.push([field, file]);
})
form.on('end', function() {
console.log('done');
//res.redirect('/forms');
});
form.parse(req);

Related

download JSON file in node Js

I am creating a json file, but not sure how to download it.
here is my code
let jsonExport= directory path;
exportTemp (name, title, id) {
let obj = new Array() ;
obj.push({Title: name, Prefix:title, UserId:id });
let file_name= jsonExport + name + ".json"
fs.writeFile(file_name, JSON.stringify(obj, null, 4), (err, response) => {
if (err) {
console.error(err);
return;
};
console.log("File has been created");
});
return (file_name);
};
If you're using express, you can simply do it like this
res.download(file_name);
or without express
app.get('/downloadFile/', (req, res) => {
var files = fs.createReadStream(file_name);
res.writeHead(200, {'Content-disposition': 'attachment; filename=demo.pdf'});
files.pipe(res)
})

formidable saves file without extension in Node js

app.post('/file_upload', function (req, res) {
var form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, '/uploads');
files = [],
fields = [];
form.on('field', function(field, value) {
fields.push([field, value]);
})
form.on('file', function(field, file) {
console.log(file.name);
files.push([field, file]);
})
form.on('end', function() {
console.log('done');
// res.redirect('/forms');
});
form.parse(req);
});
UI used to upload multiple images in nodejs using formidable
The files are being creating. But the images are getting saved without extension.
Is there anything extra steps i have to do?
This worked for me:
form.keepExtensions = true;
Try onPart:
form.on('part', function (part) {
if (part.filename) {
if (!isInvalidFileName(part.filename) || !isInvalidMimeType(part.mime)) {
files.push([part]);
}
}
})

Async series doesn't work in an order as expected

I have a function that downloads the user input(currently named app.json) from browser(client) to the server
function downloadUpload(callback){
//Using formidable node package for downloading user input to server
var form = new formidable.IncomingForm();
form.on('fileBegin', function(name, file) {
file.path = file.name;
});
form.parse(req, function(err, fields, files) {
res.writeHead(200, { 'content-type': 'text/plain' });
res.write('received upload:\n\n');
res.end(util.inspect({ fields: fields, files: files }));
});
callback(null);
}
I have another function that takes the file downloaded above and converts it into required format(final.json) something like this.
function UpdateCode(callback){
var obj = fs.readFileSync('app.json', 'utf8');
var object = JSON.parse(obj);
var data2 = [];
for (var j = 0; j < object.length; j++) {
if (object[j].value == "TEST") {
data2.push(object[j]);
}
}
console.log(data2);
fs.appendFile('final.json', JSON.stringify(data2), function(err) {
if (err) throw err;
console.log('Saved!');
});
callback(null);
}
I want them to run in an order, so I used async series method like this
async.series([
downloadUpload,
UpdateCode
],function(err,result){
if(err) throw err;
else{
console.log(result);
}
});
The problem is the file(app.json) is getting downloaded and an error is displayed saying that app.json doesn't exist in the current folder or directory. Where am I going wrong?
This is likely what you need.
function downloadUpload(callback) {
//Using formidable node package for downloading user input to server
var form = new formidable.IncomingForm();
form.on('fileBegin', function(name, file) {
file.path = "app.json";
});
form.parse(req, function(err, fields, files) {
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('received upload:\n\n');
res.end(util.inspect({
fields: fields,
files: files
}));
});
form.on('end', function() {
callback(null);
});
}
function UpdateCode(callback) {
var obj = fs.readFileSync('app.json', 'utf8');
var object = JSON.parse(obj);
var data2 = [];
for (var j = 0; j < object.length; j++) {
if (object[j].value == "TEST") {
data2.push(object[j]);
}
}
console.log(data2);
fs.appendFile('final.json', JSON.stringify(data2), function(err) {
if (err) throw err;
console.log('Saved!');
callback(null);
});
}
async.series([
downloadUpload,
UpdateCode
], function(err, result) {
if (err) throw err;
else {
console.log(result);
}
});
Also use nodemon -e js app.js. Otherwise nodemon will restart the program as soon as the json uploads.

Create new Folder with Formidable

I have the next code:
router.post('/subirArchivo', function (req, res){
var form = new formidable.IncomingForm();
form.parse(req);
form.on('fileBegin', function (name, file){
file.path = path.join(__dirname,'../../../../uploads/', file.name);
});
form.on('file', function (name, file){
console.log('Uploaded ' + file.name);
});
res.sendFile(path.join(__dirname,'../../../client/views/faseVinculacion', 'busquedaVinculacion.html'))
Upload the file it's fine, but, how create a new folder that not exists?
First you need to add fs-extra (easier way)
and in your post, add:
fs.mkdirsSync(__dirname + '/../public/dist');
form.uploadDir = __dirname + '/../public/dist';
more details:
if (req.url == '/upload') {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
fs.mkdirsSync(__dirname + '/../public/dist');
form.uploadDir = __dirname + '/../public/dist';
form
.on('field', function(field, value) {
console.log(field, value);
fields.push([field, value]);
})
.on('file', function(field, file) {
console.log(field, file);
files.push([field, file]);
})
.on('end', function() {
console.log('-> upload done');
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received fields:\n\n '+util.inspect(fields));
res.write('\n\n');
res.end('received files:\n\n '+util.inspect(files));
});
form.parse(req);
}

node.js multer saving file name into db

I'm trying to save uploaded file name into db? thanks.
Basically how can I pass multer file.name into database.
My attempt is using this var: var fileimage = file.name;
router.use(multer({ // https://github.com/expressjs/multer
dest: './uploads/',
limits : { fileSize:100000 },
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, '-').toLowerCase();
},
onFileUploadData: function (file, data, req, res) {
// file : { fieldname, originalname, name, encoding, mimetype, path, extension, size, truncated, buffer }
var params = {
Bucket: 'lemybucket01',
Key: file.name,
Body: data
};
s3.putObject(params, function (perr, pres) {
if (perr) {
console.log("Error uploading data: ", perr);
} else {
console.log("Successfully uploaded data to myBucket/myKey");
}
});
},
onFileUploadComplete: function (file) {
var fileimage = file.name;
}
}));
router.route('/')
//POST a new prod
.post(function(req, res) {
if(req.files.fileimage !== undefined){ // `image` is the field name from your form
//res.redirect("/uploads"); // success
}else{
res.send("error, no file chosen");
}
// Get values from POST request. These can be done through forms or REST calls. These rely on the "name" attributes for forms
var username = req.body.username;
//call the create function for our database
mongoose.model('Prod').create({
username : username,
fileimage : fileimage
}, function (err, prod) {
if (err) {
res.send("There was a problem adding the information to the database.");
} else {
//Prod has been created
console.log('POST creating new prod: ' + prod);
res.format({
//HTML response will set the location and redirect back to the home page. You could also create a 'success' page if that's your thing
html: function(){
// If it worked, set the header so the address bar doesn't still say /adduser
res.location("prods");
// And forward to success page
res.redirect("/prods");
},
//JSON response will show the newly created prod
json: function(){
res.json(bloprodb);
}
});
}
})
});
The req.files.fileimage !== undefined is always false?
The variable fileimage you declared in the following has limited scope
onFileUploadComplete: function (file) {
var fileimage = file.name;
}
If you want to pass some data(like fileimage) from one middleware to another you can use something like this.
onFileUploadComplete: function (file, req, res) {
var fileimage = file.name;
req.middlewareStorage = {
fileimage : fileimage//,
//otherKey : otherValue
}
}
and you can save in the db as
var fileimage = req.middlewareStorage.fileimage;
mongoose.model('Prod').create({
username : username,
fileimage : fileimage
}, function (err, prod) {
// do some stuff
});

Resources