Multiple File Upload Only Uploads The First One After Using Express File Upload
So I'm working on a function which takes in an array of file data that is acquired from user input from the front end. The files are inside req.files.fileInput which is an array of
Solution 1:
This is kind of a quick and dirty solution that should nonetheless work:
- wrap the whole loop in the
Promise
executor function. - introduce a local
count
state to keep track of the number of loop iteration that have completed successfully. - introduce a
isInError
state to keep track of whether a loop iteration has failed. - In all cases, resolve - or reject - the promise only on the first iteration that results in an error, or when all files have completed upload successfully.
constuploadFunc = (fileDataArr) => {
returnnewPromise((resolve, reject) => {
var count = fileDataArr.lengthvar isInError = falsefor (let eachFile of fileDataArr) {
const fileName = eachFile.name;
const uploadPath = `./images/${fileName}`;
eachFile.mv(uploadPath, function (err) {
if (err && !isInError) {
isInError = truereturnresolve({
success: false,
message: 'Something went wrong. Please try again!',
data: null
});
}
if (--count == 0 && !isInError) {
returnresolve({
success: true,
message: 'Files Uploaded Successfully',
data: null
});
}
});
}
});
};
Note I have stuck with your logic of resolving the promise when an error occurs - but rejecting may actually make more sense and is actually more semantically correct.
As I pointed out in the comments, look up promisifying asynchronous functions and the async/await
syntax for a cleaner solution.
Solution 2:
@IAmDranged solution is great. However, you can also do this
- Move
file.mv()
process into its own promise function calledfileMoveAsync(file)
- Map through all the files and pass each to the
fileMoveAsync(file)
- Use
Promise.all()
to await all thefileMoveAsync(file)
- If all goes well with the
Promise.all()
thenresolve
otherwisereject
promise accordingly
See code below.
The fileMoveAsync
function
const fileMoveAsync = async (file) =>
newPromise((resolve, reject) => {
const uploadPath = `./resources/images/${file.name}`;
return file.mv(uploadPath, (err) => {
if (err) {
console.error(err);
returnreject({
success: false,
message: 'Something went wrong. Please upload again!',
data: null,
});
}
returnresolve({
success: true,
message: 'File Uploaded Successfully!',
data: file.name,
});
});
});
const uploadFunc = async (file) => {
if (Array.isArray(file)) {
try {
const data = awaitPromise.all(file.map((x) =>fileMoveAsync(x)));
returnPromise.resolve({
success: true,
message: 'Files Uploaded Successfully!',
data,
});
} catch (e) {
returnPromise.reject({
success: false,
message: 'Something went wrong. Please upload again!',
data: null,
});
}
} elseif (typeof file === 'object') {
returnfileMoveAsync(file);
}
};
Use it like this
const { success, message, data } = awaituploadFunc(req.files.fileInput);
Post a Comment for "Multiple File Upload Only Uploads The First One After Using Express File Upload"