Najam Us Saqib
Najam Us Saqib

Reputation: 3402

File Upload in NodeJs with express-fileupload not working properly

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

Upvotes: 2

Views: 7643

Answers (3)

AJB
AJB

Reputation: 37

if you have installed express-fileUpload again do it with this command 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 ...

Upvotes: 0

Esteban Preciado
Esteban Preciado

Reputation: 91

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
            });
        }
    });
}

Upvotes: 2

Stock Overflaw
Stock Overflaw

Reputation: 3331

Posting an answer that may not be the answer, to explain the comment 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 completed 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 incomplete? Is it the server showing an error? The client receiving an error? In the latter cases, what error?

Upvotes: 4

Related Questions