panagulis72 panagulis72 - 8 months ago 79
HTTP Question

Send FormData with other field in Angular

I have a form with two

input text
and one
. I have to send it to the server but I have some problem concatenating the file with the text. The server expects this answer:

"title=first_input" "text=second_input" "file=my_file.pdf"

This is the html:

<input type="text" ng-model="title">
<input type="text" ng-model="text">
<input type="file" file-model="myFile"/>
<button ng-click="send()">

This is the Controller:

$scope.title = null;
$scope.text = null;

$scope.send = function(){
var file = $scope.myFile;
var uploadUrl = 'my_url';
Add.uploadFileToUrl(file, $scope.newPost.title, $scope.newPost.text, uploadUrl);

This is the Directive fileModel:

return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;

element.bind('change', function(){
modelSetter(scope, element[0].files[0]);

And this is the Service which call the server:

this.uploadFileToUrl = function(file, title, text, uploadUrl){
var fd = new FormData();
fd.append('file', file);
var obj = {
title: title,
text: text,
file: fd
var newObj = JSON.stringify(obj);

$, newObj, {
transformRequest: angular.identity,
headers: {'Content-Type': 'multipart/form-data'}
toaster.pop('error', 'Errore', error);

If I try to send, I get Error 400, and the response is:
Multipart form parse error - Invalid boundary in multipart: None
The Payload of Request is:

Answer Source

Don't serialize FormData with POSTing to server. Do this:

this.uploadFileToUrl = function(file, title, text, uploadUrl){
    var payload = new FormData();

    payload.append("title", title);
    payload.append('text', text);
    payload.append('file', file);

    return $http({
        url: uploadUrl,
        method: 'POST',
        data: payload,
        //assign content-type as undefined, the browser
        //will assign the correct boundary for us
        headers: { 'Content-Type': undefined},
        //prevents serializing payload.  don't do it.
        transformRequest: angular.identity

Then use it:

MyService.uploadFileToUrl(file, title, text, uploadUrl).then(successCallback).catch(errorCallback);