Really simple AngularJS file upload

Published at 30-07-2014

Using frameworks is totally mandatory in application industry. When I hear people who develops apps with pure language or home made framework (meaning bunch a code lines barely packaged and tested by one single personne on hearth) I usually scream internally...

There are couple of scenario where it could make sens, but for the 9x% of time, avoiding them is madness. So why some one would do such a thing ?

Learning a framework is a long process, especially if you are already struggling with language. It's easier to copy paste stuff from the web in an unstructured project (yes, i'm speaking to you, pseudo-PHP developer!). Also, framework learning is Top-Down. You start with advanced interfaces built on the top of smaller gears that you'll discover later on. This does not feat every body's mind.

And recently I faced the frustration of using a framework. I wanted to implement a file upload on an AngularJS app, and I spent way too much time on it. I give you the solution I found and some tips around framework usage:

Some research

So to give you some context, I had a form already working sending data to an API. I'm using angularjs for this purpose. Sadly Angular does not really support file input ...

Some google research gave me a list of directives on this stack-overflow post:

But all of them are advanced gear for multiple pictures upload with fancy loading bar.
I needed just a classic file input to tight with my resource.

I tried this solution too. It modifies the $httpprovider configuration to set Content-Type header to undefined to let the server discovering what is incoming by it self. Plus it uses FormData to build multi-part content of the Ajax request.

However this solution make ALL resources acting this way, that I really do not want.

Some links further, I found uor/angular-file that is closer to what I want to achieve. This directive provide support for file input. But the controller implementation didn't work with my API that was rejecting it for malformed reasons.

Then this badwing blog post gave me the final clue for the implementation. It describes a data formater factory using formData and uses $http for the request with low level control.

My solution

So I used the angular-file directive from Uor to get callback and stuff on my file input. I adapted the code from Badwing post, replacing the Content-Type to undefined (multipart is not recognized in my case).

It works, but still, I'm not really happy with it. It forced me to duplicate informations between my existing resource that cannot be used to post/put data.

FormData is a new feature not compatible with all browser versions:

FeatureChromeFirefox (Gecko)Internet Explorer OperaSafari
Basic support7+4.0 (2.0)10+12+5+
append with filenameYes22.0 (22.0)???

Also I spent a lot of time to finish this really basic feature. And I understand that people can be frustrated of using frameworks.

Wait no!

May be I spent a lot of time to deal with this, but in the overhand I learned a lot on the way:

  • Advanced used of $http
  • FormData javascript object
  • Service configuration with $httpprovider example
  • we saw some nice factories usages on the way
  • we have ready bunch of directive for mass upload
  • ...

That's the way of dealing with frameworks. It takes time, but has you increase your knowledge you get more and more tools ready and maintained! So next time you feel wasting your time dealing with unsupported features that turn out madness, remember that at the same time you are learning to make next steps easier.

I'm done.