Offline

Serializing a Function's Arguments in Javascript

At many instances when doing Ajax requests in Javascript, a serialize function comes in handy for creating a string in standard URL-encoded notation for the request parameters. The most widely used serialize function is that of jQuery which works great on forms. But what if the request is not based on values of a form?

Some Background

Consider a function who's job is to take some arguments, and perform a request with the supplied values. Also consider that there is no form involved, the first thing that comes to mind is to build the data string through concatenating the values of the arguments and we'd end up doing something like this:

function requesEmployee(name,middle,family,income) {
   var params = "name="+name+"&middle="+middle+"&family="+family+"&income="+income;

   $.ajax({
      url:"someurl",
      type:"GET",
      data: params
   });

   // etc...
}

The params string looks fine but what if there were much more parameters like 10, 15 or 20? Concatenating them would be annoying and wont look much elegant even when using something like sprintf. The ability to build such a string right from the function's argument values and names would be very powerful and that's what we're going to do.

Serializing through the Function's Arguments

As an alternative we can write a function to do the serialization for us. After all, a list of argument values on a function is easily accessible and so are the parameter names, all what we have to do after obtaining the two lists is glue them together into a string. Here is an example:

function serializeArgs(func,args,exclude) {
   exclude = exclude || [];

   var args = Array.prototype.slice.call(args,0);
   var funstr = func.toString();
   var params = funstr.slice(funstr.indexOf('(')+1, funstr.indexOf(')')).match(/([^\s,]+)/g);

   var serialized = "";

   for(var i in args) {
      if(!contains(exclude,params[i])) {
         append = (i < args.length-1)?"&":"";
         serialized += params[i]+"="+args[i]+append;
      }
   }
   return serialized;
}

function contains(arr, obj) {
   var i = arr.length;

   while(i--) {
      if(arr[i] === obj)
         return true;
   }

   return false;
}

Sample usage:

function request(name,middle,family,income) {
   var data = serializeArgs(test,arguments,['two']);
   /* Result: name=john&family=Doe&income=9000 */

   /** Rest of the code **/
}

request("John","Jim","Doe",9000);

the serializeArgs function takes 3 arguments, the called function, argument values, and an optional array of excluded parameters that we don't want to include within the serialized string. The argument values we're getting them for "free" as within any function exists a local array-like object(arguments) holding the values. As for obtaining a list of the names I converted the function into a string and sliced my way to obtain them, pretty hackish yet works well on any browser and does the job. After obtaining those two lists, building the string is a trivial, all we have to do is loop and concatenating on each index.

The contains function is optional if you're using some library which provides that functionality, such as jQuery or underscore.

I hope you find this technique useful in any of your work, would love to hear your feedback and remarks about this post, have a good day!

Enjoyed this post? Help me spread the word and let me know your feedback!

Subscribe via