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:
- The request stands as pending and it does this for a LONG time
- After about 2 minutes it throws the following errors:
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:
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?