4

I am using jQuery 1.7.1. and I have the following question/problem:

The code has as follows:

var accountObject = new Object();
accountObject.account = new Object();
accountObject.account.sas = [];

$.ajax({
    type: "PUT",
    url: "/a/2",
    data: accountObject,
    dataType: "html",
    success: function(msg) {
        alert_user("Successfully saved the selected session attributes as defaults");
    },
    error: function(msg) {
        alert_user(msg);            
    }
});

The problem is that, due to the fact that I set accountObject.account.sas to an empty array, the data arrives completely empty at the server, as:

{}

where it should have been:

{ "account": { "sas": [] } }

When I put some entries in the sas property of account then everything is ok. For example, if I put the string "1", "2" and "3" as an array ["1", "2", "3"] then I get on the server:

{ "account": { "sas": [ "1", "2", "3" ] } }

Does anybody know why this is so?

Thanks in advance Panayotis

p.matsinopoulos
  • 7,655
  • 6
  • 44
  • 92
  • 3
    `dataType: "html",` ? Try `dataType: "json"` – Joe Feb 07 '12 at 16:01
  • 2
    @JoeTuskan: the `dataType` is only responsible and needed for the returned data. – jAndy Feb 07 '12 at 16:04
  • 1
    `dataType` is irrelevant; that controls the expected response format, not the format of the query parameters. – Matt Feb 07 '12 at 16:05
  • How are you receiving the data on the server-side? from the request body? POST scope? URL scope? – Kevin B Feb 07 '12 at 16:13
  • @KevinB I am processing the request using Ruby on Rails. ```params[:account][:sas]``` should either give me an array with elements or without. But if I send empty array, ```params[:account]``` is not present at all. Please, note also, that when I were in jQuery 1.4.4 it was sending an empty string ```""``` for ```parasm[:account][:sas]```, as it is also described in [this](http://stackoverflow.com/questions/5319106/jquery-1-4-4-ajax-request-post-empty-array-or-object-becomes-string/5319127#5319127). Probably my post I can now say that it is a duplicate of that. – p.matsinopoulos Feb 08 '12 at 07:29

2 Answers2

2

The problem is that an empty array cannot be properly represented in a query string. When you pass the object hierarchy to data, jQuery will attempt to convert it to a query string, but can't figure out what to do with an empty array.

The reason why 1.4.4 seemed to return an empty string whenever it got passed the same hierarchy was that it attempted to pass the key to the query string without a value, the result of which would be like: ...&property=&. This is by default interpreted as an empty string in most server environments.

I personally consider the behavior of 1.7.1 correct, because it forces the developer to check for parameter existence instead of mucking the type of the parameter.


Some notes about various things mentioned here

  • traditional: true is completely wrong, since it can never handle object hierarchies. What you get instead is: ...&key=[object Object], which is javascript's toString() default result for all objects.

  • JSON.stringify assigned to data will result in the entire thing passed as JSON to the query string, unless you combine it with processData: false, in which case you need to deserialize into meaningful objects "by hand" on the server side. It's generally a useful option, but overkill in this case where a simple check would presumably have things working with minimal hassle.

Ioannis Karadimas
  • 7,746
  • 3
  • 35
  • 45
0

Your problem is the empty array. You can either send an empty string or according to this you try setting traditional: true

there is also this answer, which apaart from traditional also suggests using JSON.stringify. In the comments they also mention aps.net mvc model binder being the issue.

I don't how ruby achieves the equivalent of asp.net mvc's model binding, but I think this is where you should look.

Community
  • 1
  • 1
Alexandros B
  • 1,881
  • 1
  • 23
  • 36
  • I do not want to send an empty string. I want to send an empty array. So that I can treat the request on server uniformly. I have tried ```tranditional: true``` but it does not work as expected. Also, the answer on the post you direct me to is not accepted. – p.matsinopoulos Feb 08 '12 at 07:24