Despite the limitations of existing libraries, I needed to modify the content-disposition and other aspects, which I was able to achieve with guidance from this thread
While still leveraging ng-file-upload for various UI functions, I am now manually constructing the post in the controller.
(function () {
'use strict';
angular
.module('poc.fileUploads')
.controller('SignupFileUpload', SignupFileUpload);
SignupFileUpload.$inject = ['$scope','Upload', '$log', '$timeout','$location','URLS','SignupService','usSpinnerService','$anchorScroll','$http'];
function SignupFileUpload($scope, Upload, $log, $timeout, $location, URLS, SignupService,usSpinnerService,$anchorScroll,$http) {
$log.debug('ENTERING SIGNUP UPLOAD CONTROLLER %s', JSON.stringify(this));
var params = $location.search();
var customerInfo = SignupService.getCustomerInfo();
var uploadData = {};
$log.debug('CUSTOMER INFO'+JSON.stringify(customerInfo));
if (typeof Object.keys(customerInfo)[0] === 'undefined') {
$log.debug('SIGNUP - Must provide customerInfo');
$location.path('/signup');
}
$scope.uploadFiles = function(idFile,addressFile,form) {
usSpinnerService.spin('spinner');
$log.debug('Starting Upload Process to resource - ' + URLS.BASE + URLS.FILE_UPLOAD);
$log.debug('Adding customerInfoPart to uploadData');
uploadData.customerInfoPart = Upload.jsonBlob(customerInfo);
$log.debug('Checking for files to upload');
if (idFile) {
$log.debug('idFile found, adding to uploadData');
uploadData.idDocument = idFile;
}
if (addressFile) {
$log.debug('addressFile found, adding to uploadData');
uploadData.addressDocument = addressFile;
}
$log.debug('Upload data - ' + JSON.stringify(uploadData));
$log.debug('Uploading data');
var epochTicks = 621355968000000000;
var ticksPerMillisecond = 10000;
var yourTicks = epochTicks + ((new Date()).getTime() * ticksPerMillisecond);
var boundary='---------------------------'+yourTicks;
var header='--'+boundary+'\r\n';
var footer='\r\n--'+boundary+'--\r\n';
var contenttype='multipart/form-data; boundary='+boundary;
var jsonContents=header+'Content-Disposition: form-data; name="customerInfoPart"\r\n';
jsonContents+='Content-Type: application/json\r\n';
jsonContents+='Content-Length: '+JSON.stringify(customerInfo).length+'\r\n\r\n';
jsonContents+=JSON.stringify(customerInfo)+'\r\n';
var idFileContents=header+'Content-Disposition: form-data; name="idDocument"; filename="'+$scope.idFile.name+'"\r\n';
idFileContents+='Content-Transfer-Encoding: binary\r\n';
idFileContents+='Content-Type: '+ $scope.idFile.type+'\r\n';
idFileContents+='Content-Length: '+ $scope.idFile.size +'\r\n\r\n';
var idFileReader = new FileReader();
var addressFileContents=header+'Content-Disposition: form-data; name="addressDocument"; filename="'+$scope.addressFile.name+'"\r\n';
addressFileContents+='Content-Transfer-Encoding: binary\r\n';
addressFileContents+='Content-Type: '+$scope.addressFile.type+'\r\n';
addressFileContents+='Content-Length: '+$scope.addressFile.size+'\r\n\r\n';
var addressFileReader = new FileReader();
var blob=new Blob([jsonContents,idFileReader.readAsArrayBuffer($scope.idFile),idFileReader,addressFileReader.readAsArrayBuffer($scope.addressFile),addressFileReader,footer]);
$log.debug(blob.toString());
$http.post(
URLS.BASE + URLS.FILE_UPLOAD,
blob,
{'headers':{'Content-Type':contenttype}}
).success(function (data, status, headers, config) {
// file is uploaded successfully
usSpinnerService.stop('spinner');
$log.debug('Upload Status - ' + status);
$timeout(function () {
$scope.serverMessage = data;
});
if (status===204) {
$location.path('/signup-confirmation');
SignupService.setCustomerSignupStatus(true);
}
}).error(function (data, status, headers, config) {
// handle error
$log.debug('Signup failed with status ' + status);
handleError(status);
});
};
function handleError(error) {
usSpinnerService.stop('spinner');
scrollToServerMessage();
$scope.serverMessage = 'Signup failed with status ' + error.status;
}
function scrollToServerMessage() {
var old = $location.hash();
$location.hash('serverMessage');
$anchorScroll();
//reset to old to keep any additional routing logic from kicking in
$location.hash(old);
}
}
}());