Request: Post with empty array in form removes the property

Created on 15 Aug 2017  ·  3Comments  ·  Source: request/request

Summary


It appears that there is some form of optimization in the form when posting. This is bad for me, it removes properties from the form.
I'm trying to send an object with a property holding an array which could be empty.
Every time the array is empty an MissingPropertyError is being returned which is incorrect as the empty array actually holds value over not having the property at all.

Simplest Example to Reproduce

const request = require( 'request' )
const bodyParser = require('body-parser')
const app = require('express')()

app.use( bodyParser.json() )
app.use( bodyParser.urlencoded( { extended: true } ) )

app.post('/', function( req, res ){
    console.log( 'received:', req.body )
    res.send('ok')
})
app.listen( 53153 )

const req = {
    url: 'http://localhost:53153',
    method: 'POST',
    headers: {
        'Content-Type' : 'application/x-www-form-urlencoded'
    },
    form: {
        emptyArray: [],
        filledArray: [{something:[]}]
    }
}
console.log( 'sending:', req )
request( req , function( err, httpResponse, body ){
    process.exit(0)
})

Expected Behavior




I expected the send object to be received, as it is valid json

$ node index.js
sending: { url: 'http://localhost:53153',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  form: { emptyArray: [], filledArray: [ { something: [] } ] }
received: { emptyArray: [], filledArray: [ { something: [] } ] }

Current Behavior



Turns out the received object is nothing but an empty object, looking at wireshark the content-length being sent is 0.

$ node index.js
sending: { url: 'http://localhost:53153',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  form: { emptyArray: [], filledArray: [ { something: [] } ] }
received: {}

adding null to the array changes behavior:

$ node index.js
sending: { url: 'http://localhost:53153',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  form: { emptyArray: [ null ], filledArray: [ { something: [ null ] } ] }
received: { emptyArray: [ '' ], filledArray: [ { something: [ '' ] } ] }

however adding undefined in the arrays does not change behavior:

$ node index.js
sending: { url: 'http://localhost:53153',
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  form: { emptyArray: [ undefined ], filledArray: [ { something: [ undefined ] } ] }
received: {}

Possible Solution


Context


Your Environment

| software | version
| ---------------- | -------
| request | 2.81.0
| node | 8.3.0
| npm | 5.1.0
| Operating System | Ubuntu 16.04.2 LTS

stale

Most helpful comment

can't believe that none of the folks working on this project have any input on this. the answer above is invalid as it does not understand the use case mentioned. Why are we providing a sample for "application/json" when clearly the question is about" application/x-www-form-urlencoded". This is an issue happening still but sadly is not given attention.

In my test, the undefined and empty arrays will disappear in the results and anything 'null' will appear in the url-encoded-string.

a json of:
{ results: { arr1: [], arr2: undefined, arr3: null, foo: { arr4: [] } } }
will yield a url with only
"?results%5Barr3%5D="

All 3 comments

So, it appears that the JSON object is getting converted into a string and is being set as the body of the request before being sent. This is the default behavior when you specify the 'form' attribute. The method that this library uses to convert JSON to a string removes empty arrays. What you need to do is instead of passing in the 'form' attribute, pass in the 'body' attribute and JSON.stringify your JSON object to convert it into a string. For example:

NOTE: YOU MIGHT HAVE TO MESS WITH THE HEADERS AND USE application/json as the content type. I haven't experimented to see what works.

{
    url: 'http://localhost:53153',
    method: 'POST',
    headers: { 'Content-Type': 'application/json'},
    body: JSON.stringify({ emptyArray: [], filledArray: [ { something: [] } ] })
}

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

can't believe that none of the folks working on this project have any input on this. the answer above is invalid as it does not understand the use case mentioned. Why are we providing a sample for "application/json" when clearly the question is about" application/x-www-form-urlencoded". This is an issue happening still but sadly is not given attention.

In my test, the undefined and empty arrays will disappear in the results and anything 'null' will appear in the url-encoded-string.

a json of:
{ results: { arr1: [], arr2: undefined, arr3: null, foo: { arr4: [] } } }
will yield a url with only
"?results%5Barr3%5D="

Was this page helpful?
0 / 5 - 0 ratings

Related issues

IgorDePaula picture IgorDePaula  ·  3Comments

svlungade picture svlungade  ·  3Comments

mlegenhausen picture mlegenhausen  ·  4Comments

jasonxia23 picture jasonxia23  ·  3Comments

lupo9557 picture lupo9557  ·  3Comments