pillarOfLight
pillarOfLight

Reputation: 8982

ajax POST not sending part of object

So I have this code:

var ajaxUrl = 'a/7776/as';
var data = {
    'answer' : {  'user_input'    : []  },
    'form_build_id' : 'form-ffe6f10e9601470ed4cfe38257a959a6'
}
 $.ajax({
    url: ajaxUrl,
    dataType: 'json',
    type: 'POST',
    data: data,
    success: function(json){
    }
  });

However when I inspected the POST source it appears that 'answer' is not being sent..

Here's the POST source in Firebug:

Parametersapplication/x-www-form-urlencoded
form_build_id   form-ffe6f10e9601470ed4cfe38257a959a6
Source
form_build_id=form-ffe6f10e9601470ed4cfe38257a959a6

Why is this the case and how can I get it to also send the 'answer' part of the object into the AJAX post?

Upvotes: 5

Views: 1933

Answers (4)

p e p
p e p

Reputation: 6674

Nice explanation from T.J. Crowder, clearly knowledgeable. Here's my take at a practical answer. I inspected my HTTP traffic and ran your above AJAX request. As expected, answer was not being sent. Also going along with adrenalin's answer above, if you search for "ajax not sending empty array" on google, you can see just by the number of related results that this is also an issue. What I would do is if user_input is an empty array, send null instead. I tried it myself to make sure and, again as expected, this time I observed the answer parameter being sent in the request, along with user_input which was sent as null with the code below.

var userInput = []; //not sure where this is coming from in reality, but this is just an example.

if (userInput.length == 0){  //in this example, this is obviously always true
    userInput = null;
}
var ajaxUrl = 'a/7776/as';

var data = {
    'answer' : {  'user_input'    : userInput  },
    'form_build_id' : 'form-ffe6f10e9601470ed4cfe38257a959a6'
}
$.ajax({
    url: ajaxUrl,
    dataType: 'json',
    type: 'POST',
    data: data,
    success: function(json){
    }
});

Upvotes: 0

adrenalin
adrenalin

Reputation: 1658

Because you cannot post a zero length array. POST (or HTTP query) keys do not carry any type information and zero length array would effectively build into null in a POST body: message = [] will serialize into ''.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074495

The default POST encoding is multipart/form-data, which consists of a flat series of name=value pairs.

Your structure cannot be mapped directly to a flat series of name=value pairs, because it's complex. You have a member which is an object, which has a property referring to an array.

If you want to send an arbitrarily-complex structure, you have to use a different encoding and ensure that the server understands that encoding. For instance, you can send JSON or XML to the server, but you have to tell it that's what you're doing by setting the contentType property on the ajax method (which sets the type of the data you're sending to the server). Then your server has to understand how to deserialize that JSON or XML.

Alterately, ensure that your structure can be mapped to a flat series of name=value pairs.

A half-way house is to send data as multipart/form-data, but where you send a single name=value pair and have the value part be a different encoding, like this:

$.ajax({
    url: ajaxUrl,
    dataType: 'json',
    type: 'POST',
    data: {json: JSON.stringify(data)},
    success: function(json){
    }
});

That sends a single name=value pair with the name json, where the value is a JSON-encoded string. Your server-side would retrieve the value of the json parameter in the normal way, and then use a JSON deserializer to recreate the object graph.

This half-way-house technique is sometimes handy in frameworks that make it difficult to use something other than standard request encoding.

Upvotes: 3

zs2020
zs2020

Reputation: 54524

You need to set traditional to true if you want the payload contains an array.

$.ajax({
    url: ajaxUrl,
    dataType: 'json',
    type: 'POST',
    data: data,
    traditional: true,
    success: function (json) {}
});

Upvotes: 0

Related Questions