I have looked around and looked at various tutorials on how to upload a file using node/express. I feel like I am doing something wrong on either the HTML or JQuery side.
I am using the following link as a http://howtonode.org/really-simple-file-uploads.
However I am getting the error:
TypeError: Cannot read property 'fileUpload' of undefined at module.exports.fileCreate
Here is my code below:
uploadcontroller.js
fs.readFile(req.files.fileUpload.path, function (err, data) {
var newPath = __dirname + "/uploads/" + imgString;
fs.writeFile(newPath, data, function (err) {
});
});
html snippet
<div class="form-group">
<label for="fileUpload">Upload File</label>
<input type="file" name="fileUpload" id="fileUpload">
</div>
I am using the Sails framework (not sure if that makes difference)
Edit: Complete Form
<form role="form" class="uploadFileForm">
<div class="form-group">
<label for="fileTitleInput">Title</label>
<input type="text" name="formTitleInput" id="formTitleInput">
</div>
<div class="form-group">
<label for="fileDescriptionInput">Description</label>
<textarea class="form-control" rows="4" id="fileDescriptionInput"></textarea>
</div>
<div class="form-group">
<label for="fileUpload">Upload File</label>
<input type="file" name="fileUpload" id="fileUpload">
</div>
<button type="submit" class="btn btn-default" id="file-submit-btn">Publish to Web</button>
</form>
app.post('/upload', function(req, res) {
fs.readFile(req.files.image.path, function (err, data) {
var imageName = req.files.image.name
/// If there's an error
if(!imageName){
console.log("There was an error")
res.redirect("/");
res.end();
} else {
var newPath = __dirname + "/uploads/fullsize/" + imageName;
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
/// let's see it
res.redirect("/uploads/fullsize/" + imageName);
});
}
});
});
app.post('/', function(req, res) {
console.log(req.files);
fs.readFile(req.files.displayImage.path, function (err, data) {
var newPath = __dirname + "/uploads/"+req.files.displayImage.name;
fs.writeFile(newPath, data, function (err) {
if (err) throw err;
res.redirect("back");
});
});
});
Just for your reference, "console.log(req.files)" would contain something like this:
{ displayImage:
{ domain: null,
_events: null,
_maxListeners: 10,
size: 84654,
path: 'E:\\Users\\xyz\\AppData\\Local\\Temp\\90020831e2b84acb2d4851e4d4
2d77d5',
name: 'ccc - 1.jpg',
type: 'image/jpeg',
hash: false,
lastModifiedDate: Wed May 22 2013 07:47:39 GMT+0530 (India Standard Time),
_writeStream:
{ domain: null,
_events: null,
_maxListeners: 10,
path: 'E:\\Users\\xyz\\AppData\\Local\\Temp\\90020831e2b84acb2d4851e
4d42d77d5',
fd: 4,
writable: false,
flags: 'w',
encoding: 'binary',
mode: 438,
bytesWritten: 84654,
busy: false,
_queue: [],
_open: [Function],
drainable: true },
length: [Getter],
filename: [Getter],
mime: [Getter] }
}
I ran into the same problem. Sails did not recognize req.files (undefined). So your problem seems very much Sails related. The following solved my problem (especially the Skipper documentation).
In the 0.9 version of Sails, you can uncomment this line in the config/express.js file:
// bodyParser: require('express').bodyParser,
In the 0.10 version, use req.file instead of req.files.
See their beta documentation on file uploads: http://beta.sailsjs.org/#/documentation/reference/Upgrading
Be sure to check out the Skipper documentation as well: https://github.com/balderdashy/skipper. Most likely your version of Sails will use this to process the file uploads.
Related
I am trying to save a HTML Canvas image to MongoDB using Multer.
To test if my backend ( node + mongoose ) is working correctly, I created a form to upload the images I already have and that is saving to the database successfully.
To save the canvas image, I am making a JQuery ajax POST request after converting the image to a File. I am doing this inside the external JavaScript of the static drawing app which also contains few event listeners. I get this error:
data: fs.readFileSync(path.join(__dirname + '/../uploads/' + req.file.filename)),
^
TypeError: Cannot read properties of undefined (reading 'filename')
the external JS:
async function submitDrawing(username){
if(mode==0) context.fillStyle = 'white';
else context.fillStyle = 'black';
context.globalCompositeOperation = 'source-over';
context.clearRect(0, 0, saveCanvas.width, saveCanvas.height);
context.fillRect(0, 0, saveCanvas.width, saveCanvas.height);
context.drawImage(canvass,0,0);
await saveCanvas.toBlob(blob => {
var image = new File([blob], "image");
var name = $("#name").value;
let fd = new FormData();
fd.append("name",name);
fd.append("username",username);
fd.append("image",image);
$.ajax({
method : "POST",
url : "http://localhost:5000/postDrawing",
body: fd,
enctype: 'multipart/form-data',
processData: false, // don't let jquery process the data
contentType: false,
cache: false
})
});
}
In the node app, this is routes.js :
//importing all necessary stuff...
var multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({ storage: storage });
router.post('/postDrawing',upload.single('image'),postDrawing);
postDrawing function :
const postDrawing = async (req, res, next) => {
//creating object according to the mongoose schema I have.
var obj = {
name: req.body.name,
username: req.body.username,
img: {
data: fs.readFileSync(path.join(__dirname + '/../uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
let im = new imgModel();
im.name = obj.name;
im.username = obj.username;
im.img = obj.img;
const temp = await im.save();
//res.send(temp);
}
the form which uploads to database successfully, just for reference :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Uploading</title>
</head>
<body>
<h1>To Upload Image on mongoDB</h1>
<hr>
<div>
<form action="/postDrawing" method="POST" enctype="multipart/form-data">
<div>
<label for="name">Image Title</label>
<input type="text" id="name" placeholder="Name"
value="" name="name" required>
</div>
<div>
<label for="username">username</label>
<textarea id="username" name="username" value="" rows="2"
placeholder="username" required>
</textarea>
</div>
<div>
<label for="image">Upload Image</label>
<input type="file" id="image"
name="image" value="" required>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
</body>
</html>
please help me out in uploading the canvas image to database.Thank you.
I have to create a route that uploads 1 audio file and 1 image (resized) to Cloudinary using Multer Storage Cloudinary, and save the url and name in my mongo database.
I get the error "Invalid image file" when I try to upload the audio file (even if I delete transformation and add "mp3" in allowedFormats.
Cloudinary code:
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET
});
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
// transformation: [
// {width: 500, height: 500, crop: "fill"}
// // ],
// allowedFormats: ['jpeg', 'png', 'jpg', 'mp3']
}
});
module.exports = { cloudinary, storage }
Route code:
router.route("/")
.get(catchAsync(sounds.index));
.post(isLoggedIn, upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]), joiValidationSounds, catchAsync(sounds.newSound));
module.exports.newSound = async (req, res) => {
const sound = new Sound(req.body.sound);
console.log(req.files)
sound.image.url = req.files["sound[image]"][0].path;
sound.image.filename = req.files["sound[image]"][0].filename;
sound.audio.url = req.files["sound[audio]"][0].path;
sound.audio.filename = req.files["sound[audio]"][0].filename;
sound.author = req.user._id;
await sound.save();
req.flash("success", "Se ha añadido un nuevo sonido.");
res.redirect(`/sounds/categories/:category/${sound._id}`);
}
Form code:
<form action="/sounds" method="POST" novalidate class="validated-form" enctype="multipart/form-data">
<div class="row mb-3">
<label for="audio" class="col-sm-2 col-form-label">Audio:</label>
<div class="col-sm-10">
<input type="file" name="sound[audio]" id="audio">
</div>
</div>
<div class="row mb-3">
<label for="image" class="col-sm-2 col-form-label">Imagen:</label>
<div class="col-sm-10">
<input type="file" name="sound[image]" id="image">
</div>
</div>
<button type="submit" class="btn btn-success">Crear</button>
<button type="reset" class="btn btn-success">Limpiar</button>
</form>
I can upload 2 images instead without problems. I also checked that Cloudinary supports mp3 files.
EDIT: I managed to upload the audio with resource_type: 'video', allowedFormats: ['mp3'], and 2 different storages.
But now I get the error "Unexpected field" when I try to upload both.
New code:
const storageAudio = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
format: 'mp3',
resource_type: 'video',
allowedFormats: ['mp3'],
}
});
const storageImage = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
transformation: [
{width: 500, height: 500, crop: "fill"}
],
format: 'jpg',
resource_type: 'image',
allowedFormats: ['jpeg', 'png', 'jpg']
}
});
module.exports = { cloudinary, storageImage, storageAudio };
const multer = require("multer");
const { storageImage, storageAudio } = require("../cloudinary");
const uploadAudio = multer({ storage: storageAudio });
const uploadImage = multer({ storage: storageImage });
router.route("/")
.get(catchAsync(sounds.index))
.post(isLoggedIn,
// uploadAudio.fields([{ name: 'sound[audio]', maxCount: 1 }]), uploadImage.fields([{ name: 'sound[image]', maxCount: 1 }]),
uploadAudio.single("sound[audio]"),
uploadImage.single("sound[image]"),
// upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),
joiValidationSounds, catchAsync(sounds.newSound)
);
When uploading files to Cloudinary, one of the upload parameters is the resource_type, telling Cloudinary how to process the incoming file. The possible values are 'image', 'video', 'raw' (non-image, non-video), or 'auto' (where the file will be opened after upload to check the type)
If you're getting the Invalid image file error when uploading a video, most likely it means that the resource_type on the upload call was set to 'image', and looking at the repo of the plugin you're using, that appears to be the case: https://github.com/affanshahid/multer-storage-cloudinary/issues/13
You may need to contact the plugin maintainer and see if they can allow overriding the resource type in a future release, or fork the plugin to allow the resource type to be overridden in the configuration
Alternatively, you can use Cloudinary's SDK directly to perform the upload, and use multer just to make the uploaded file available to your code. In which case the Cloudinary SDK uses resource_type "auto" by default when uploading, and you can override the value in your own code if needed
Finally, I found a solution (with one storage and one form) to upload both image and audio:
1)Set the params to resource_type: 'auto', and allowedFormats to all the formats you will upload.
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
resource_type: 'auto',
allowedFormats: ['jpeg', 'png', 'jpg', 'mp3'],
transformation: [
{width: 500, height: 500, crop: "fill"}
]
}
});
2)Use upload.fields
upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),
I'm building a website where user needs to fill a form with information as first name, last name, profile picture, number etc... I've already code the form and I'm looking a way with node js to upload the image in a specific directory (or a default directory) and store the information that the users filled in my database. I use node js and Express with mysql.
UPDATE:
(I used formidable package and util package).
Please notice that for the image part, I only need the path( you will see it on the ouput section).
form code:
<form method="post" action="upload" enctype="multipart/form-data">
<fieldset>
<input type="file" accept="image/*" name="image" required /><br/>
<label for="Prenom">Prénom: </label>
<input type="text" name="user_prenom" id="Prenom" required /><br/>
<label for="Nom">Nom: </label>
<input type="text" name="user_nom" id="Nom" required /><br/>
<label for="Mail">E-Mail: </label>
<input type="email" name="user_mail" id="Mail" required/><br/>
<label for="Pays">Pays: </label>
<input type="text" name="user_pays" id="Pays" required/><br/>
<label for="Ville">Ville: </label>
<input type="text" name="user_ville" id="Ville" required/><br/>
<label for="Num">Numéro: </label>
<input type="tel" name="user_telephone" id="Num" /><br/>
<input type="submit" />
</fieldset>
</form>
handle:
router.post('/upload', function(req, res) {
processFormFieldsIndividual(req, res);
});
function processFormFieldsIndividual(req, res) {
//Store the data from the fields in your data store.
//The data store could be a file or database or any other store based
//on your application.
var fields = [];
var form = new formidable.IncomingForm();
form.uploadDir = "/public/photo_utilisateurs";
//Call back when each field in the form is parsed.
form.on('field', function (field, value) {
fields[field] = value;
});
//Call back when each file in the form is parsed.
form.on('file', function (name, file) {
fields[name] = file;
//Storing the files meta in fields array.
//Depending on the application you can process it accordingly.
});
//Call back for file upload progress.
form.on('progress', function (bytesReceived, bytesExpected) {
var progress = {
type: 'progress',
bytesReceived: bytesReceived,
bytesExpected: bytesExpected
};
//Logging the progress on console.
//Depending on your application you can either send the progress to client
//for some visual feedback or perform some other operation.
});
//Call back at the end of the form.
form.on('end', function () {
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('received the data:\n\n');
res.end(util.inspect({
fields: fields
}));
});
// var user = JSON.parse(fields);
// connection.query('INSERT INTO Utilisateurs (user_nom, user_prenom, user_mail, user_phone, user_pays, user_ville) VALUES ("' + user.user_nom + '", "' + user.user_prenom + '", "' + user.user_mail + '", "' + user.user_pays + '", "' + user.user_ville + '", "' + user.user_telephone + '")',
// function selectCb(err, results, fields) {
// if (err) throw err;
// else res.send('success');
// });
form.parse(req);
}
The Output
received the data:
{ fields:
[ user_prenom: 'dfw',
user_nom: 'efwe',
user_mail: 'efew#fref',
user_pays: 'efwe',
user_ville: 'efwe',
user_telephone: '4380564324',
image: File {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
size: 518,
path: '/tmp/upload_e611ea0745206682b26c208d816dc604',
name: '1462507431_play_now_sign_youtube_video.svg',
type: 'image/svg+xml',
hash: null,
lastModifiedDate: Mon May 09 2016 00:16:24 GMT-0400 (EDT),
_writeStream: [Object] }
]
}
You can simply declare the Global variable and assign the form fileds to it. And use it where you want.
var data = util.inspec({
data: fields
});
console.log(data);
});
form.on('end', function () {
res.writeHead(200, {
'content-type': 'text/plain'
});
res.write('received the data:\n\n');
// console.log(fields.name+'-'+fields.nickname);
var values={
name:fields.name,
nickname:fields.nickname,
email:fields.email,
password:fields.password,
dob:fields.dob,
gender:fields.gender,
phoneno:fields.phone
};
connection.query('INSERT INTO users SET ?', values, function(err,req,res){
if(err){
console.log('Connection result error '+err);
}
else{
console.log('Success');
}
});
res.end();
});
I am trying to figure out how it is possible to pass an array as the value for the property of an instance. I currently have the dataType set to STRING in my model and have values from jQuery fields insert each form field value into an array that I parse from the body and set to the property, discoverSource. Unfortunately I receive a string violation error that says I can't use an array or object. What does this mean and how can I change the dataType of the field or route to allow me to pass the comma separated values to the field?
E.x. For discoverySource I pass values to two fields (NJ, NY). On submit, the values are combined in an array as ["NJ", "NY"] and the error displays:
Error Message:
{"name":"SequelizeValidationError","message":"string violation: discoverySource cannot be an array or an object","errors":[{"message":"discoverySource cannot be an array or an object","type":"string violation","path":"discoverySource","value":["NJ","NY"]}]}
Here is my model:
module.exports = function(sequelize, DataTypes) {
var Organization = sequelize.define('organization', {
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
autoIncrement: true,
primaryKey: true
},
organizationName: {
type: DataTypes.STRING,
field: 'organization_name'
},
admin: DataTypes.STRING,
discoverySource: {
type: DataTypes.TEXT,
field: 'discovery_source'
},
members: DataTypes.STRING
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.belongsToMany(db.User, { through: 'member', foreignKey: 'user_id' });
},
},
});
return Organization;
}
Here is the route:
var express = require('express');
var appRoutes = express.Router();
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
appRoutes.route('/sign-up/organization')
.get(function(req, res){
models.User.find({
where: {
user_id: req.user.email
}, attributes: [ 'user_id', 'email'
]
}).then(function(user){
res.render('pages/app/sign-up-organization.hbs',{
user: req.user
});
})
})
.post(function(req, res, user){
models.Organization.create({
organizationName: req.body.organizationName,
admin: req.body.admin,
discoverySource: req.body.discoverySource
}).then(function(organization, user){
res.redirect('/app');
}).catch(function(error){
res.send(error);
console.log('Error at Post' + error);
})
});
Here is my view file:
<!DOCTYPE html>
<head>
{{> head}}
</head>
<body>
{{> navigation}}
<div class="container">
<div class="col-md-6 col-md-offset-3">
<form action="/app/sign-up/organization" method="post">
<p>{{user.email}}</p>
<input type="hidden" name="admin" value="{{user.email}}">
<input type="hidden" name="organizationId">
<label for="sign-up-organization">Company/Organization Name</label>
<input type="text" class="form-control" id="sign-up-organization" name="organizationName" value="" placeholder="Company/Organization">
Add Another Discovery Source
<div id="sign-up-organization-discovery-source">
<input type="text" id="discovery-source-field" placeholder="Discovery Source" name="discoverySource[0]">
</div>
<br />
<button type="submit">Submit</button>
</form>
Already have an account? Login here!
</div>
</div>
<script type="text/javascript">
$(function() {
var dataSourceField = $('#sign-up-organization-discovery-source');
var i = $('#sign-up-organization-discovery-source p').size();
var sourceCounter = 1;
$('#sign-up-add-discovery-source').on('click', function() {
$('<p><label for="discovery-source-field"><input type="text" id="discovery-source-field" size="20" name="discoverySource['+ sourceCounter++ +']" value="" placeholder="Discovery Source" /></label> Remove</p>').appendTo(dataSourceField);
i++;
return false;
});
$('#sign-up-organization-discovery-source').on('click', '.remove', function() {
if (i > 1) {
$(this).parent('p').remove();
i--;
}
return false;
});
});
</script>
</body>
To answer the last comment, I need to be able to make the code more readable, so I'm posting it here in a new answer.
Having thought about it a little more, it would make more sense to add it as custom 'getter' function. I'll also include the 'instanceMethods' to demonstrate how that works, as well.
var Organization = sequelize.define('organization', {
...
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.belongsToMany(db.User, { through: 'member', foreignKey: 'user_id' });
},
},
// Here's where custom getters would go
getterMethods: {
discoverySources: function() {
return this.getDataValue('discoverySource');
}
},
// here's the instance methods
instanceMethods: {
getSourcesArray: function() {
return this.getDataValue('discoverySource');
}
}
});
Both of these options add the functions to each instance created by the Model. The main difference being in how they are accessed.
organization.discoverySources; // -> ['s1', 's2', etc...]
organization.getSourcesArray(); // -> ['s1', 's2', etc...]
note the additional () required on the instanceMethod. Those are added as functions of the instance, the getterMethods get added as properties.
setterMethods work the same way to allow you to define custom setters.
Hope that clarifies things a bit.
Hi i am trying to do ajax image upload.this is the work i got so far.
my index.html:
//index.html
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>File Upload showing Upload Progress</title>
<style>
* {
font-family: Verdana;
font-size: 12px;
}
</style>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data" id="MyUploadForm">
<input name="ImageFile" id="imageInput" type="file" />
<input type="submit" id="submit-btn" value="Upload" />
<img src="images/ajax-loader.gif" id="loading-img" style="display:none;" alt="Please Wait"/>
</form>
<div id="output"></div>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.min.js'></script>
<script type='text/javascript' src='main.js'></script>
</body>
<script type="text/javascript" src="js/jquery.form.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
target: '#output', // target element(s) to be updated with server response
beforeSubmit: beforeSubmit, // pre-submit callback
resetForm: true // reset the form after successful submit
};
$('#MyUploadForm').submit(function() {
$(this).ajaxSubmit(options); //Ajax Submit form
// return false to prevent standard browser submit and page navigation
return false;
});
});
//function to check file size before uploading.
function beforeSubmit(){
alert('ok');
//check whether browser fully supports all File API
if (window.File && window.FileReader && window.FileList && window.Blob)
{
if( !$('#imageInput').val()) //check empty input filed
{
$("#output").html("Are you kidding me?");
return false
}
var fsize = $('#imageInput')[0].files[0].size; //get file size
var ftype = $('#imageInput')[0].files[0].type; // get file type
//allow only valid image file types
switch(ftype)
{
case 'image/png': case 'image/gif': case 'image/jpeg': case 'image/pjpeg':
break;
default:
$("#output").html("<b>"+ftype+"</b> Unsupported file type!");
return false
}
//Allowed file size is less than 1 MB (1048576)
if(fsize>1048576)
{
$("#output").html("<b>"+fsize +"</b> Too big Image file! <br />Please reduce the size of your photo using an image editor.");
return false
}
$('#submit-btn').hide(); //hide submit button
$('#loading-img').show(); //hide submit button
$("#output").html("");
}
else
{
//Output error to older unsupported browsers that doesn't support HTML5 File API
$("#output").html("Please upgrade your browser, because your current browser lacks some new features we need!");
return false;
}
}
</script>
</html>
and my app.js
var express = require('express'); //Express Web Server
var bodyParser = require('body-parser'); //connects bodyParsing middleware
var formidable = require('formidable');
var path = require('path'); //used for file path
var fs =require('fs-extra'); //File System-needed for renaming file etc
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
/* ==========================================================
bodyParser() required to allow Express to see the uploaded files
============================================================ */
app.use(bodyParser({defer: true}));
app.route('/').get(function(req,res)
{
console.log("Server started!");
res.render('index.html');
res.end('done');
});
app.post('/upload', function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(files);
res.send('fileinfo: ' +files);
});
});
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
I am getting the follwing response on server-side:
{ ImageFile:
{ domain: null,
_events: {},
_maxListeners: undefined,
size: 238027,
path: '/tmp/a7b06a71ff10de78cc8b941b18762b73',
name: 'bg.jpg',
type: 'image/jpeg',
hash: null,
lastModifiedDate: Sun Jun 01 2014 04:05:57 GMT+0530 (IST),
_writeStream:
{ _writableState: [Object],
writable: true,
domain: null,
_events: {},
_maxListeners: undefined,
path: '/tmp/a7b06a71ff10de78cc8b941b18762b73',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
pos: undefined,
bytesWritten: 238027,
closed: true } } }
Now i want to know.How to move this file into upload folder. And also when i submit it goes in another page.I want to perform it without reloading is there any way for it in node? Thanks in advance.
fs-extra module has move method. Use it like this:
app.post('/upload', function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
fs.move(files.ImageFile.path, __dirname + '/upload/' + files.ImageFile.name, function(err) {
if (err) return console.log(err);
console.log('Moved successfully');
});
res.send('fileinfo: ' + files);
});
});
So the uploaded file appears in upload folder with the original name. There are 2 caveats:
upload folder should exist;
if file with such name exists already it will not be overwritten, so maybe you should generate a unique filename on each upload (replace files.ImageFile.name with your unique filename).