I have made a REST API in NodeJs for File Upload working okay but there is an Issue, if i upload more then 2 images only 2, 3 get uploads and sometimes 1 gets corrupted. i think my Loop is running too fast for this. blow is my Code:
app.post('/img-upload', function(req, res) {
if (!req.files)
return res.status(400).send({"status":"false", "data":"Image Not Found"});
// Use the mv() method to place the file somewhere on your server
for(var key in req.files) {
thisFile = req.files[key];
let name = +new Date();
thisFile.mv('./images/' + name++ +'.png', function(err) {
if (err) {
res.send(err);
}
});
}
res.json({"status":"File uploaded!"});
});
module used: express-fileupload
I have made a REST API in NodeJs for File Upload working okay but there is an Issue, if i upload more then 2 images only 2, 3 get uploads and sometimes 1 gets corrupted. i think my Loop is running too fast for this. blow is my Code:
app.post('/img-upload', function(req, res) {
if (!req.files)
return res.status(400).send({"status":"false", "data":"Image Not Found"});
// Use the mv() method to place the file somewhere on your server
for(var key in req.files) {
thisFile = req.files[key];
let name = +new Date();
thisFile.mv('./images/' + name++ +'.png', function(err) {
if (err) {
res.send(err);
}
});
}
res.json({"status":"File uploaded!"});
});
module used: express-fileupload
-
res.json()
might be causing the request to close before the file uploads finish. You have to wait until each of the callbacks have pleted. – Patrick Roberts Commented Jan 25, 2019 at 13:46 - can you explain More! – Najam Us Saqib Commented Jan 25, 2019 at 13:56
-
It's possible that two files are being moved to the same destination path. Like you said, the loop flies pretty quickly. Calls to
new Date()
will most likely return same value for two iterations. One solution is to move the counter variablename
outside of the loop body. – pspi Commented Aug 19, 2019 at 5:22
3 Answers
Reset to default 4Posting an answer that may not be the answer, to explain the ment by @PatrickRoberts who seems to have a point.
thisFile.mv
apparently works asynchronously, meaning function(err){...}
might be run after res.json(...)
and the following implicit return
.
Although Node shouldn't kill the remaining async processes, you're anyway too early to tell the user that files were uploaded successfully. (You could send that success, then one of your callbacks throws an error... but too late, you can't send that error to the client.)
Two options to see this through.
a decent option
Wait for all callbacks to be pleted to send a successful result. Probably something like:
let uploads = [];
for (let k in req.files) {
req.files[k].mv('/my/path/to.png', function(err) {
let promise = new Promise(function(resolve, reject) {
if (err) {
reject(err);
} else {
resolve();
}
});
uploads.push(promise);
})
} // end for loop
Promise.all(uploads).then(function() {
res.json({"status":"File uploaded!"});
}).catch(function(err) {
res.send(err);
});
a slow option that I'm ashamed of
In case this doesn't fix it, and assuming @PatrickRoberts spotted the correct issue, you can try and make the uploads sequentially, like:
function processFile() {
let file = req.files.shift()
if (!file) return; // stop sequence condition
file.mv('/my/path/to.png', function(err) {
if (err) {
res.send(err);
} else {
processFile();
}
})
}
processFile(); // start the recursive and sequential "loop"
If none of these work (the second, bad option is slow but a clear proof of whether res.json
/res.send
are involved), then your issue lies elsewhere. In such a case, please give more information about "sometimes one is corrupted": is the file inplete? Is it the server showing an error? The client receiving an error? In the latter cases, what error?
this work for me
let media = req.files;
for (let pos in media) {
media[pos].mv(`./media/${renameFile}`, (err) => {
if (err) {
return res.status(500).json({
ok: false,
err
});
}
});
}
if you have installed express-fileUpload again do it with this mand if you want to upload image kindly give name attribute (case sensitive ) and try
npm install express body-parser cors express-fileupload morgan lodash --save
for me it worked ...