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

How to append an object? #92

Closed
petermilan opened this issue Dec 3, 2014 · 17 comments
Closed

How to append an object? #92

petermilan opened this issue Dec 3, 2014 · 17 comments

Comments

@petermilan
Copy link

Hello need to append object field something like:

var form = new FormData();
form.append('name', 'Name');
form.append('details', {age: 12});

but it will throw an error like this:

      TypeError: Object #<Object> has no method 'on'

      at Function.DelayedStream.create (/home/pity/workspace/node_modules/cmp-uploaders/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
      at FormData.CombinedStream.append (/home/pity/workspace/node_modules/cmp-uploaders/node_modules/combined-stream/lib/combined_stream.js:43:37)
      at FormData.append (/home/pity/workspace/node_modules/cmp-uploaders/node_modules/form-data/lib/form_data.js:43:3)
      at validationFailTest (/home/pity/workspace/node_modules/cmp-uploaders/test/lab/simple_uploader.js:68:6)
      at Object._onImmediate (/home/pity/workspace/node_modules/cmp-uploaders/node_modules/lab/lib/execute.js:492:17)
      at processImmediate [as _immediateCallback] (timers.js:330:15)
@alexindigo
Copy link
Member

Hey,

The thing is you can send only strings over the wire, so complex data types, like object should be encoded somehow and since there are many way to encode objects, FormData leaves it to developer to choose proper encoding mechanism that supported on the other end. For example it could be a JSON string or a form-urlencoded string.

Something like:

var details = JSON.stringify({age: 12});
form.append('details', details);

Let me know if you have more questions.

@petermilan
Copy link
Author

Hello,
thanks for the response. My use case is that I am using this module just in my tests to simulate the form post to the hapijs server.

I've already tried JSON.stringify but unfortunately, the field was arriving as a string instead of an object. I don't want to add into my production code logic to parse some of the fields from string to json just because of tests:(

@alexindigo
Copy link
Member

You'd need to handle decoding one way or another and because implementations differ from server to server, you need to find combination that would work for your setup.

One of the ways is to stay away from nested structure, something like:

var form = new FormData();
form.append('name', 'Name');
form.append('age', '12');

or

var form = new FormData();
form.append('name', 'Name');
form.append('details_age', '12');

or PHP-style (not sure if Hapi would support it out of the box):

var form = new FormData();
form.append('name', 'Name');
form.append('details[age]', '12');

Another solution will be to encode all your data as JSON and send it to the server with proper headers,
there should be examples in Hapi documentation.

@petermilan
Copy link
Author

Thanks php style helped for hapi, I thought that I' ve already tried this, but obviously I had some bug there before :)

@NodeGuy
Copy link

NodeGuy commented May 28, 2015

How about if append receives an object then it assumes it should be encoded with JSON.stringify and it sets Content-Type to application/json? This seems like a common use case to me.

It wouldn't be worse than the current behavior of TypeError: Object #<Object> has no method 'on'.

@alexindigo
Copy link
Member

it maybe common case for some apps, but some other apps work with url-encoded data, and even with url-encoding there are multiply ways, like standard HTTP way and PHP array-friendly way.

And if all you need is JSON.stringify, there should be no problem in doing it in "user"-land (i.e. form.append('data', JSON.stringify(myData)), right?

Throwing errors in general meant for developer errors, to notify developer of the unacceptable behavior. And for developers it's much easier to find out about the problem this way, then somewhere deeper in stack because some library took freedom to assume things for the developer, especially for dynamic languages like JS, where you can accidentally pass object instead of a string.

@NodeGuy
Copy link

NodeGuy commented May 28, 2015

Excellent points, I agree.

@mifi
Copy link

mifi commented Oct 30, 2017

Is there any npm module for transforming an object to PHP style array? recursively

@mifi
Copy link

mifi commented Oct 30, 2017

@amrrizk95
Copy link

amrrizk95 commented Jun 17, 2020

i can not append list of objects to my form data i got empty list on the action

$.each(selectLists, function (key, selectList) { var SingelValue = { ItemId: singleList.id, inputValue: singleList.value } SingelValue = JSON.stringify(SingelValue); fdata.append("SingelValues[]", SingelValue) }

@FuyaoLi2017
Copy link

I use Swagger2.0, mongoDB as database and I am trying to go with the stringify() during sending and decode in the Flask server side.
Surprisingly, even though I defined the schema in the swagger UI for such field as string. During get fields, it will still directly get the json array instead of string format... This satisfies my need, but it doesn't make sense. Could someone give me an explanation on this?

@alexsmartens
Copy link

I was trying to post a complex data structure without pickling it into json to set up a simple data flow from React to Rails, and this thread was the most helpful piece of information. Just in case someone is looking for an example:

data to be posted:

{
  library: "favorite",
  movie: {
    name: "James Bond Skyfall",
    year: "2012",
    screenshots: [file1, file2],
  },
}

implementation with FormData:

const formData = new FormData()

formData.append("library", "favorite")
formData.append("movie[name]", "James Bond Skyfall")
formData.append("movie[year]", "2012")

formData.append("movie[screenshots][]", file1)
formData.append("movie[screenshots][]", file2)

@abned08
Copy link

abned08 commented May 18, 2021

can I append the Object as it is, without Stringify it?

@Joserbala
Copy link

Joserbala commented Sep 29, 2021

@abned08 no, you may stringify it or use @alexsmartens's solution. FormData.append() only accepts USVString and Blob.

@alex-el11
Copy link

Thanks a lot to @alexsmartens for example. I was 3, 4 days without can send objects in FormData post and his example really help me to success.
e.g (C#):
public JsonResult AddTicketUser(TicketViewModel ticketVM) //ticketVM has a Ticket object inside.

I believe that @alexindigo is elegant solution but I not sure how implements in my case. ( Use enctype: 'multipart/form-data' and contentType: false).

greetings :)

@garsax
Copy link

garsax commented Nov 23, 2022

Following @alexsmartens example here's a handy js function to append an object to FormData

function FormData_append_object(fd, obj, key) {
  var i, k;
  for(i in obj) {
    k = key ? key + '[' + i + ']' : i;
    if(typeof obj[i] == 'object')
      FormData_append_object(fd, obj[i], k);
    else
      fd.append(k, obj[i]);
  }
}

And here's is how you would call it:

var myObject = { a: 'one', b: { b1: 'two', b2: { b21: 'three', b22: 'four' } }, d: 'five' };
fd = new FormData();
FormData_append_object(fd, myObject);

It works great calling ajax from js to PHP.

@jorgeramirezamora
Copy link

Hey,

The thing is you can send only strings over the wire, so complex data types, like object should be encoded somehow and since there are many way to encode objects, FormData leaves it to developer to choose proper encoding mechanism that supported on the other end. For example it could be a JSON string or a form-urlencoded string.

Something like:

var details = JSON.stringify({age: 12});
form.append('details', details);

Let me know if you have more questions.

In case this is useful for somebody else, in the case you are using Express Multer you can use file.buffer.toString()

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