21

I have to send a file (very large file) to a server. I'm studying what options I have and how to do it. I'm using angular + express + nodejs.

If I use a simple form, I could catch the file on the server using multer with no problem. Is very simple. The html is just a form, in which I specify the target etc. and everything works. The nodejs code is also very simple and straight forward.

As soon as I try to use angular, everything becomes incredible complicated. Meaning, I have to use a directive, and still have trouble with the server. As I said I'm using multer, which requires the data to be "multipart/form-data", and I get from the server "Error: Multipart: Boundary not found"

There are many modules to load files in angular. Which shows that is a recurrent problem with more than one solution. Now, I don't want to post code because for that I asked at Stack Overflow. My question is more subtle:

Why what can be done with a simple form, get's so complicated in angular? I don't mean it in a bad way. I mean it in a 'I want to understand' way.

cauchi
  • 1,192
  • 2
  • 13
  • 22
  • is this somehow related to [your recent question at Stack Overflow](http://stackoverflow.com/q/30080966/839601)? "How do I solve the error 'Boundary not found' and what does it means..." – gnat May 06 '15 at 15:44
  • 2
    Yes, that's why I put the link on the question. But here I don't want to solve the problem. I would like to know why is it a problem in the first place. – cauchi May 06 '15 at 15:51

1 Answers1

23

Angular is for Single Page Applications, forms are sent using AJAX to avoid the page to be reloaded. For sending multipart forms with AJAX, your browser need to support FormData(IE10+): http://caniuse.com/#search=FormData

https://developer.mozilla.org/en-US/docs/Web/API/FormData

ngModel doesn't work with input[type="file"], so you have to create your own directive. Your own directive should be simple: on change, update a File object on your scope.

When sending your form, create a FormData object and add your file(s) to it using FormData.set or FormData.append. You can send your FormData with $http or $resource, and you are relying on the browser for setting the content-type and boundary.

var formData = new FormData();
formData.append('file', $scope.file);
$http.post('yourUrl', formData, {
   transformRequest: angular.identity,
   headers: {'Content-Type': undefined}
}).then(function () {
   // ...
});

angular.identity prevents Angular to do anything on our data (like serializing it).

I recommend this article: https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

Thomas Roch
  • 396
  • 3
  • 4