1

Sorry about the long title.

So i am creating an angular application with a node server as my backend. I have previously made the following route to upload:

router.route('/resource')
.post(function (req, res) {
    req.files.file.originalname = req.files.file.originalname.replace(/ +?/g, '_');
    if (validate(req.body.type, req.files.file)) {
        var path = createPath(req.body, req.user.user_id);
        if (path) {
            var media = new mediaModule.Media(req.files.file, path);
            processData(media).then(function (result) {
                res.json(result);
                if (req.body.update == 'true' && req.body.oldResource) {
                    deleteFile(req.body.oldResource);
                }
            })
        } else {
            res.status(500).send('Incorrect path!');
        }
    } else {
        res.status(500).send('Validation failed!');
    }
})

The above code has been tested and works like a charm.

Now as you guys know you create directives in Angular. one of my directives is an uploader it looks like this:

    /**
 * Scope variables:
 * lbUploadForm: {location: STRING(required), location_id: INTEGER (semi required), update: boolean, oldResource: STRING (if update = true then required) } (REQUIRED)
 * uploadType: STRING (OPTIONAL)
 * strictAccept: STRING (OPTIONAL)
 * objectPointer: object (OPTIONAL)
 * tokenField: STRING (OPTIONAL)
 * layoutSize: STRING (REQUIRED)
 * uploadCallback: function (OPTIONAL) (RECOMMENDED)
 */
angular.module('ResourceManager').directive('lbUploader', ['Query', 'FileUploader', 'ResourceFactory', function (Query, FileUploader, ResourceFactory) {
    return {
        restrict: 'E',
        roles: 'admin',
        templateUrl: getTemplate,
        scope: {
            lbUploadForm: '=',
            uploadType: '@',
            strictAccept: '@',
            objectPointer: '=',
            tokenField: '@',
            layoutSize: '@',
            uploadCallback: '='
        },
        link: function (scope, element, attr) {
            scope.uploader = new FileUploader({
                url: ResourceFactory.getUploadUrl(),
                formData: [scope.lbUploadForm]
            });

            scope.footable = function (timeout) {
                setTimeout(function () {
                    $('.footable').trigger('footable_resize');
                    $('.footable').trigger('footable_redraw');
                }, timeout);
            };

            // CALLBACKS
            scope.uploader.onWhenAddingFileFailed = function (item /*{File|FileLikeObject}*/, filter, options) {
                console.info('onWhenAddingFileFailed', item, filter, options);
            };
            scope.uploader.onAfterAddingFile = function (fileItem) {
                console.info('onAfterAddingFile', fileItem);
            };
            scope.uploader.onAfterAddingAll = function (addedFileItems) {
                console.info('onAfterAddingAll', addedFileItems);
            };
            scope.uploader.onBeforeUploadItem = function (item) {
                console.info('onBeforeUploadItem', item);
            };
            scope.uploader.onProgressItem = function (fileItem, progress) {
                console.info('onProgressItem', fileItem, progress);
            };
            scope.uploader.onProgressAll = function (progress) {
                console.info('onProgressAll', progress);
            };
            scope.uploader.onSuccessItem = function (fileItem, response, status, headers) {
                console.info('onSuccessItem', fileItem, response, status, headers);
            };
            scope.uploader.onErrorItem = function (fileItem, response, status, headers) {
                console.info('onErrorItem', fileItem, response, status, headers);
            };
            scope.uploader.onCancelItem = function (fileItem, response, status, headers) {
                console.info('onCancelItem', fileItem, response, status, headers);
            };
            scope.uploader.onCompleteItem = function (fileItem, response, status, headers) {
                if (status == 200) {
                    if (scope.uploadCallback != null) {
                        scope.uploadCallback(fileItem, response);
                    } else {
                        if (scope.tokenField && scope.objectPointer) {
                            scope.objectPointer[scope.tokenField] = response;
                        }
                    }
                }

                scope.uploader.onCompleteAll = function () {
                    console.info('onCompleteAll');
                    scope.uploader.clearQueue();
                    angular.element("input[type='file']").val(null);
                };
            }
        }
    };

    function getTemplate(element, attr) {
        var templateUrl = '';
        var dirPath = 'js/helpers/ResourceManager/directives/lb-uploader/';

        switch (attr.layoutSize) {
            case 'xl':
            case 'lg':
            case 'md':
                templateUrl = dirPath + 'lb-uploader-big.html';
                break;
            case 'sm':
            case 'xs':
                templateUrl = dirPath + 'lb-uploader-small.html';
                break;
            default:
                templateUrl = dirPath + 'lb-uploader-big.html';
                break;
        }

        return templateUrl;
    }
}]);

Now the above also works to well and has been tested and used multiple places in my application.

The problem

Okay now i go around my usual business i have a place in my application where my users want to upload files

So i add my directive:

<lb-uploader ng-hide="CTRL.course.caption" strict-accept="image/*" lb-upload-form="CTRL.formData" layout-size="sm" upload-callback="CTRL.captionUploadCallback"></lb-uploader>

And attempt to upload.

But this time something odd happends and il walk you through it:

  1. The request stands as pending and it does this for a LONG time
  2. After about 2 minutes it throws the following errors:

enter image description here

Then after it has thrown this again it attempts to upload the file again and this time it succeeds

In total this process takes around 4 - 5 minutes.

Now i attempted to put a break point in my node server at the following point:

    app.all('/', function (req, res, next) {
    // CORS headers
    res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    // Set custom headers for CORS
    res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
    next();
});

I then debugged the server but the request never made it to this point.

Also the request that is pending has the following headers:

enter image description here

Please note that this is the ONLY place in my whole application (which is rather large) where it stalls and i am using the same upload method on all places in my application.

Does anyone have any clue of what might cause this?

Community
  • 1
  • 1
Marc Rasmussen
  • 19,771
  • 79
  • 203
  • 364
  • Which body-parser are you using? Does it allow multipart forms? – zeronone Jul 07 '16 at 10:07
  • @zeronone Do you mean in node? if so im using: https://www.npmjs.com/package/body-parser – Marc Rasmussen Jul 07 '16 at 10:09
  • as far as I know `body-parser` doesn't support multipart bodies. http://stackoverflow.com/questions/23114374/file-uploading-with-express-4-0-req-files-undefined – zeronone Jul 07 '16 at 10:14
  • @zeronone The odd thing is after the request has stalled it reattempts to upload and it works fine. And all other places where i use the uploader it works fine. Can you see something that i cannot? – Marc Rasmussen Jul 07 '16 at 10:17

0 Answers0