Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FormData should not be passed to $http config as data #504

Closed
jayrmotta opened this issue Jan 12, 2015 · 5 comments
Closed

FormData should not be passed to $http config as data #504

jayrmotta opened this issue Jan 12, 2015 · 5 comments

Comments

@jayrmotta
Copy link

Method append undefined on the FormData instance passed to the formDataAppender function.

Steps to reproduce:
1 - Install angular-http-case-converter
2 - Install angular-upload-file
3 - Configure an input file as the rails example (with the formDataAppender function)
4 - Run the application and try to upload something

angular-upload-file version: 2.1.1
angular: 1.3.3
angular-http-case-converter: 0.1.1

Long explanation:

I'm using angular-http-case-converter to normalize formats between JavaScript (camelCase) and Ruby (snake-case), so during the transformation process it creates a new object transfering the properties of the original object to the new one while converting their format.

The problem is that the object being passed when I use angular-file-upload is FormData and this process replaces the original object making an error occur when the request transformer calls the append method that doesn't exist on the new object created by the interceptor that converted the format.

@danialfarid
Copy link
Owner

There is a difference between the data being used in $http and $upload. For http the data is being sent as one json object so processing could happen on the whole object but for $upload the properties specified in the data: {p1: 1, p2: 2} are treated as form data fields. That's like when you are uploading using regular html form and you have some fields that are being send along with the file as part of multipart/form-data request. This way on the server side you can access those fields by their name from the request body. So for $upload transformRequest functions will be called on the value of each property not the data object itself.

If you want to modify the property names at the root level of data then you can either do it before sending it to $upload or since version 2.2.0 you can specify option sendDataAsJson:true which will convert the whole data as one object to json and send it with the form data name data.
This way the transformRequest will be called on the whole data object and you can modify it as you want.
The only difference is that on the server side the form data name is 'data' which contains the whole data object and individual properties will not be added to multipart form data.

@jayrmotta
Copy link
Author

Hi Danial, congratulation for the great job you've been doing with angular-file-upload!

Maybe I've failed to explain myself, but passing it as an object or as field names is indifferent to who is passing the object, but for the chain of interceptors it is way different, and both ways are subject to the encoding phase that will get the data passed and serialize it to be transmitted and then used by the server-side.

The thing is that angular-file-upload internally passes a FormData instance to $http and it becomes impossible to modify or even read its properties before the request is made except for the transformRequest function that executes right before the request is made. The suggestion I've made/implemented/pull-requested is that internally we pass the original data object to $http and just when the transformRequest executes we transform that object in a FormData instance.

This will allow interceptors to work with that data object as a common object and when the time is right we convert it to a FormData instance along with the file and encode it in a way $http is able to make the correct request.

Does it make sense?

@danialfarid
Copy link
Owner

I see what you mean now. Yea I think your approach is cleaner.
I will consider it for the next release, it might change how the other options in the plugin.

@danialfarid
Copy link
Owner

Version 3.0.0 will not touch the data option and will send it as form data field with the name data to the server by default. If you set sendObjectsAsJsonBlob it will send it as json blob otherwise json strings.
There is also an option 'fields' which is similar to form data field and each key in that object will be sent individually as one form data field.

@jayrmotta
Copy link
Author

👍 congratulations and thanks for fixing it so quickly ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants