Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling uploads with skipper in sails.js (on progress)

I am using skipper to upload multiple files at once to a local folder. But I ran into few problems.

upload: function (req, res) {
    if (_.isEmpty(req.session.User)){
        return res.json({                                       //---> 1
                    success: 0
               });
    }else{
        res.setTimeout(0);
        var MAXBYTES = 10*1000*1000;

                                                                //---> 2
        if (req._fileparser.form.bytesExpected > MAXBYTES){
            return res.json({
                success: 0,
                error: 'File size limit exceeded.'
            });
        }else{

            req.file('file[]').on('progress', function(event){
                return event;                                   //---> 3
            }).upload({

                maxBytes: MAXBYTES

            }, function whenDone(err, uploadedFiles) {
                                                                //---> 4
                    return res.json({
                        success: 1,
                    });

            });
        }
    }
},

first error //---> 1 If the user is not logged in I want to end this upload process and return success = 0. This is not working. At the client side the request is kept hanging without any response.

second error //---> 2 I ran into an error earlier as described here https://github.com/balderdashy/skipper/issues/36 and so as a quick fix I used what someone used in the comments at github. But again as in problem 1, I ran into this issue. If the file size exceeds that of MAXBYTES, I want to end this upload process and return success = 0 to the user. The isn't going back to the client side.

third error //---> 3 I want to use on progress to create a progress bar. But I quickly ran into few issues. First of all, using on progress slows the system down too much. Also it leads to an error in the 4th step.

fourth error //---> 4 If we remove the on('progress') from step 3, this works as expected. On completing upload, it returns success = 1 to the client. However, when on('progress') is present return res... in step //---> 4 doesn't work and once again the client request is kept hanging without any response.

Few questions: Why doesn't the following code work in //---> 1 while it works in //---> 4 if on('progress') is not present

return res.json({
   success: 0
});

Why does the on progress slow down the upload process so much?

Btw on my client side I use the form.js plugin. And therefore my request looks like this:

$('#upload').ajaxForm({
    uploadProgress: function(event, position, total, percentComplete){
        console.log(percentComplete);
    },
    success: function(data) {
        console.log(data);
    }
});
like image 330
pewpewlasers Avatar asked Oct 05 '14 18:10

pewpewlasers


1 Answers

It took me some time to solve this, and by the time I did, I had completely forgotten about my question here at stackoverflow. These are some of the steps I took to make this work.

upload: function (req, res) {
    if (_.isEmpty(req.session.User)){
        return res.json({   // or destroy connection as shown below
            success: 0
        });
    }else{
        res.setTimeout(0);
        var MAXBYTES = 10*1000*1000;

        if (req._fileparser.form.bytesExpected && req._fileparser.form.bytesExpected > MAXBYTES) {
            // file size exceeded //-> also check filesize on client-size before uploading because this will not send error report back to the client
            req.connection.destroy();
        }

        req.file('file[]').on('progress', function(event){
            // returning anything here was unnecessary
            // For example jQuery form plugin's client-side `uploadProgress:` will still catch the progress
        }).upload({
            maxBytes: MAXBYTES
        }, function whenDone(err, uploadedFiles) {
            var tempFileNames = _.pluck(uploadedFiles, 'fd');
            if (_.isEmpty(tempFileNames)) {
                return res.json({
                    success: 0,
                    error: '0 files selected.'
                });
            }else{
                // process upload
                return res.json({
                    success: 1,
                });
            }
        });
    }
},

This is still not the best solution. I actually find some of it hacky. If anyone has a better solution, please do share.

like image 110
pewpewlasers Avatar answered Nov 08 '22 04:11

pewpewlasers