Reputation: 17
A coach in my application can upload an image for his profile, clients, programs and exercise.
After the file has been upload, the nodejs server rename it. Then the nodejs server needs to insert / update the image name on the db, according to the form that sends the image (registration, edit user, add client, edit client and so on...).
Therefore I want to send additional data / parameters to the nodejs function.
HTML:
<form name="userUpdateForm" action="/university/uploadImage" method="post" enctype="multipart/form-data" id="editUserForm">
<label>Replace Logo Image</label></br>
<input id="uploadFile" name="filetoupload" type="file">
<input type="submit">
</form>
Node:
router.post('/uploadImage', function (req,res,next) {
var newpath = "";
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.path;
var time = new Date();
var newImageName = time.getHours() + "-" + time.getMinutes() + "-" + time.getSeconds() + "-" + files.filetoupload.name;
newpath = './uploaded/' + newImageName;
//sendToDbImageName(newImageName);
fs.readFile(oldpath, function (err, data) {
if (err) throw err;
console.log('File read!');
// Write the file
fs.writeFile(newpath, data, function (err) {
if (err) throw err;
console.log('File uploaded and moved!');
console.log('File written!');
res.redirect(url + '?uid=' + globalUid + '#/editUser');
});
// Delete the file
fs.unlink(oldpath, function (err) {
if (err) throw err;
console.log('File deleted!');
});
});
});
});
Update: This is how I solved that:
One function that's takes an image from different forms (coach, client, program, exercise), generate unique file name, and insert / update the database.
Don't repeat; check, Don't go twice to the server; check, Prevent redirect after file was upload; check.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname + '/../uploaded')
},
filename: function (req, file, cb) {
var time = new Date();
cb(null, time.getHours() + "-" + time.getMinutes() + "-" +
time.getSeconds() + "-" + file.originalname) //Appending extension
}
})
var upload = multer({ storage: storage });
router.post('/uploadImage', upload.single('avatar'), function (req, res, next) {
var formName = req.body.formName;
switch (formName) {
case "editUser":
var sql = "UPDATE coachdirectory SET logo = '" + req.file.filename + "' WHERE uid = '" + req.body.uid + "'";
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result.affectedRows + " record(s) updated");
});
res.redirect(url + '/?uid=' + req.body.uid + '#/yourClients');
break;
case "registerUser:
other business logic
break;
}
});
Upvotes: 0
Views: 2556
Reputation: 3194
The best practice is using Multer package developed by ExpressJS. Server handling file upload is really difficult, so they created multer which is basically built on top of busboy. There are some edge cases you also need to handle when you do it by scratch. No need of reinventing the wheel. Better use Multer as you can pass normal formal data in multipart itself. Multer will attach those to req.body by default.
In Multer, you have the flexibility to rename the file before saving it the database itself or keep the original filename.
Upvotes: 2