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

Unable to pass in an object to formData #1495

Closed
joshuamcginnis opened this issue Mar 19, 2015 · 12 comments
Closed

Unable to pass in an object to formData #1495

joshuamcginnis opened this issue Mar 19, 2015 · 12 comments

Comments

@joshuamcginnis
Copy link

It seems that whenever I add an object (such as the to object below) to formData, I get an error. If I remove the to object or change it to a string, I no longer get an error.

Why is this?

var fs      = require('fs');
var request = require('request');
var file    = './test/assets/test.pdf';

var opts = {
  url: 'my_service',
  method: 'POST',
  auth: { user: 'username', password: 'password' },
  json: true,
  formData: {
    front: fs.createReadStream(file),
    to: {
      name: 'joe bob',
      address_1: '123 main st',
      ...
    }
  }
};

request(opts, function(err, resp, body) {
  console.log(err, body);
});

Error:

/sandbox/project/node_modules/request/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js:33
  source.on('error', function() {});
         ^
TypeError: undefined is not a function
    at Function.DelayedStream.create (/Users/me/sandbox/project/node_modules/request/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
    at FormData.CombinedStream.append (/Users/me/sandbox/project/node_modules/request/node_modules/combined-stream/lib/combined_stream.js:43:37)
    at FormData.append (/Users/me/sandbox/lproject/node_modules/request/node_modules/form-data/lib/form_data.js:43:3)
    at appendFormValue (/Users/me/sandbox/project/node_modules/request/request.js:466:21)
    at Request.init (/Users/me/sandbox/project/node_modules/request/request.js:477:11)
    at new Request (/Users/me/sandbox/project/node_modules/request/request.js:264:8)
    at request (/Users/me/sandbox/project/node_modules/request/index.js:50:10)
    at Object.<anonymous> (/Users/me/sandbox/project/test.js:30:1)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
@joshuamcginnis
Copy link
Author

This works for now ...

var opts = {
  url: 'my_service',
  method: 'POST',
  auth: { user: 'username', password: 'password' },
  json: true,
  formData: {
    front: fs.createReadStream(file),
    'to[name]': 'joe bob',
    'to[address_1]': '123 main st'
  }
};

@kruchone
Copy link

kruchone commented May 1, 2015

That is the correct way to handle this, as the library form-data which request uses does not have support for appending anything but strings to the data.

@kengz
Copy link

kengz commented Jul 1, 2015

Hey there just tried to do the same thing,
Since the right way pointed above is probably not the most efficient,
I've written a method in my library for this; it flattens the JSON for formData.
Just putting this out for anyone to use it: flattenJSON

@simov
Copy link
Member

simov commented Jul 1, 2015

I don't think that there is a standard way to handle object parameters outlined in the spec, although the flattenJSON method seems to be really nice for such cases.

@funkyLover
Copy link

how about this situation
i got a formdate like that

var formData = {
  body: {
    header: {
      token: token,
      username: username
    },
    pageUrl: pageUrl
  }
  file: fs.createReadStream(self.file)
};

@fdefitte
Copy link

The flattenJSON works great for me too, thanks @kengz !
formData : _.flattenJSON(formData) does the trick

@arshadkazmi42
Copy link

This Options structure worked for me for POST request

var opts = {
            url: url,
            method: method,
            headers: headers,
            json: true,
            body: formData
        };

@DylanPiercey
Copy link

You can checkout q-flat for converting nested objects to valid form data objects.

@xseignard
Copy link

xseignard commented Sep 5, 2017

What about arrays of arrays?
Such as the guide parameter on the facebook video api: https://developers.facebook.com/docs/graph-api/reference/user/videos/#Creating (chapter Parameters > sourceparam)

It expects something like:

formData: {
	guide_enabled: 1,
	guide: [[2, -90, 0], [4, 0, 180], [6, 90, -180]],
	description: opts.message,
	source: fs.createReadStream(videoPath),
},

So I try to send the following:

formData: {
	guide_enabled: 1,
	'guide[0][0]': 2,
	'guide[0][1]': -90,
	'guide[0][2]': 0,
	'guide[1][0]': 4,
	'guide[1][1]': 0,
	'guide[1][2]': -180,
	'guide[2][0]': 6,
	'guide[2][1]': 90,
	'guide[2][2]': 180,
	description: opts.message,
	source: fs.createReadStream(videoPath),
},

But it's not working. Any idea?

@dylanh724
Copy link

This really not intuitive -- is there a reason why this doesn't work? I encountered the same issue.

var formData {
  thisWorksFine: "foo",
  doesntWorkWithAwfulErrCatching: {
    ping: "pong"
  }
};

The error is "TypeError: source.on is not a function"

I searched for hours to find this was the reason D:

@rbren
Copy link

rbren commented Oct 9, 2018

The custom_file example in the documentation implies that this should work. Would suggest removing that example from the README if this is no longer supported.

@lushang
Copy link

lushang commented Jun 26, 2019

This does work, but if you pass a JSON into the formData, you shoud stringify it:

var fs      = require('fs');
var request = require('request');
var file    = './test/assets/test.pdf';

var jsonData = {
  name: 'joe bob',
  address_1: '123 main st',
  ...
}
var opts = {
  url: 'my_service',
  method: 'POST',
  auth: { user: 'username', password: 'password' },
  json: true,
  formData: {
    front: fs.createReadStream(file),
    to: {
      value : JSON.stringify(jsonData),
      options : {
        contentType: 'application/json'
      }
    }
  }
};

request(opts, function(err, resp, body) {
  console.log(err, body);
});

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