Busboy - is there a way to send a response when all files have been downloaded?

I am trying to upload files to the server using node.js as the backend and angular.js as the interface. For this I use express 4 + busboy. I have a table in the interface where I have to display all the files that I upload. Therefore, if I have 3 files and click on download, angular should send these files to node.js, and after receiving a response, update the table with these three files. This is the function I use in angular:

function uploadFiles(files){ var fd = new FormData(); for(var i = 0; i<files.length; i++){ fd.append("file", files[i]); } $http.post('http://localhost:3000/upload', fd, { withCredentials: false, headers: {'Content-Type': undefined }, transformRequest: angular.identity }).success(refreshTable()).error(function(){ console.log("error uploading"); }); } 

and this is from node.js:

 app.post('/upload', function(req, res) { var busboy = new Busboy({ headers: req.headers }); busboy.on('file', function (fieldname, file, filename) { console.log("Uploading: " + filename); var fstream = fs.createWriteStream('./files/' + filename); file.pipe(fstream); }); busboy.on('finish', function(){ res.writeHead(200, { 'Connection': 'close' }); res.end(""); }); return req.pipe(busboy); }); 

the problem is that if I upload three files, as soon as the first file is uploaded, node.js will send a response, and therefore the table will only be updated with the first uploaded file, if I refresh the page, the rest of the files appear. I think the problem is with this line in node: return req.pipe (busboy); if I delete this line, the response to the message will be waiting for a long time and nothing will happen, I think this is an asynchronous problem, does anyone know if there is a way to send the answer only when all the files have been downloaded? thanks

+5
source share
1 answer

A simple and common solution to this particular problem is to use a counter variable and listen for the finish event in the fs Writable stream. For instance:

 app.post('/upload', function(req, res) { var busboy = new Busboy({ headers: req.headers }); var files = 0, finished = false; busboy.on('file', function (fieldname, file, filename) { console.log("Uploading: " + filename); ++files; var fstream = fs.createWriteStream('./files/' + filename); fstream.on('finish', function() { if (--files === 0 && finished) { res.writeHead(200, { 'Connection': 'close' }); res.end(""); } }); file.pipe(fstream); }); busboy.on('finish', function() { finished = true; }); return req.pipe(busboy); }); 

The reason for this is that the busboy finish event is emitted after the entire request has been fully processed, including files. However, there is some delay between when there is no more data to write to a specific file, and when the OS / node flushed its internal buffers to disk (and closing the file descriptor). Listening to the finish event for the fs stream being recorded lets you know that the file descriptor has been closed and there will be no more recording.

+6
source

All Articles