This is a bit of a rant, but also a very serous question. jQuery has changed ajax param serialization as follows:
jQuery 1.4 adds support for nested param serialization in jQuery.param, using the approach popularized by PHP, and supported by Ruby on Rails. For instance, {foo: [“bar”, “baz”]} will be serialized as “foo[]=bar&foo[]=baz”.
Did you catch that?
You call your parameter foo. jQuery now renames that to foo[] behind your back if foo’s value is an array. The reason for this is because some PHP-ers and Rubyists expect 3rd party APIs to rename things for them.
Call me old fashioned, but when I put something into a map, with key x, I expect to find the value under x. Or at least have this the default behavior with an optional override.
Even the documentation agrees with me:
If value is an Array, jQuery
serializes multiple values with same
key i.e. {foo:[“bar1”, “bar2”]}
becomes ‘&foo=bar1&foo=bar2’.
Am I right in thinking this is simply a bad judgment call from the jQuery team?
It’s actually filling in a major inconsistency, if your deserializer is aware of the convention and works with it nicely. It makes an array-of-one-thing look different from a thing-on-its-own.
Old:
foo: "bar"maps to"foo=bar"maps tofoo: "bar".foo: ["bar"]maps to"foo=bar"maps tofoo: "bar".foo: ["bar", "baz"]maps to"foo=bar&foo=baz"maps tofoo: ["bar", "baz"].New:
foo: "bar"maps to"foo=bar"maps tofoo: "bar".foo: ["bar"]maps to"foo[]=bar"maps tofoo: ["bar"].foo: ["bar", "baz"]maps to"foo[]=bar&foo[]=baz"maps tofoo: ["bar", "baz"].And now everything roundtrips nicely and you don’t have to worry about receiving array data or non-array data depending on how many elements were in the array to begin with. For maximum elegance,
foo: []should also serialize tofoo[](a key with no value), indicating a 0-ary list, but jQuery 1.4 doesn’t do that. Maybe it should. 🙂