I’m using Prototype JavaScript library and today I have learned one thing. To make Your life easier do not use JavaScript Arrays as arguments for AJAX calls.
I’m talking about parameters
option in Ajax objects (Ajax.Request
, Ajax.Updater
, etc). Let’s take simple HTML snippet (public/test.html
):
<div id="out"></div> <script src="/javascripts/prototype.js" type="text/javascript"></script> <script type="text/javascript"> addr = [] addr[1] = 2 new Ajax.Updater ("out", "/controllers/test", {parameters: addr }) </script>
Now simple Controller
controller :)
class ControllersController < ApplicationController def test render :layout => false end end
And test.html.erb
:
<%= debug params %>
Simple, isn’t it? What do You expect to be displayed when You point Your browser to /test
? Something like:
--- !map:HashWithIndifferentAccess action: test "1": "2" controller: controllers
Wrong!
Real output is like:
--- !map:HashWithIndifferentAccess uniq: |- function (sorted) { return this.inject([], function (array, value, index) {if (0 == index || (sorted ? array.last() != value : !array.include(value))) {array.push(value);}return array;}); } without: |- function () { var values = $A(arguments); return this.select(function (value) {return !values.include(value);}); } size: |- function () { return this.length; } zip: |- function () { var iterator = Prototype.K, args = $A(arguments); if (Object.isFunction(args.last())) { iterator = args.pop(); } var collections = [this].concat(args).map($A); return this.map(function (value, index) {return iterator(collections.pluck(index));}); } toArray: |- function () { return [].concat(this); } findAll: |- function (iterator, context) { iterator = iterator.bind(context); var results = []; this.each(function (value, index) {if (iterator(value, index)) {results.push(value);}}); return results; } [CUT]
What is going on?
It seems that it is some bug with serialization of Arrays. Prototype does iterate through all properties, and dumps them not matter if it property is function or not (maybe Prototype has own reasons for that behavior). So how to get output like in the first dump? Use Hash, Luke:
// addr = [] addr = {}
Does work as expected.
Leave a Reply