We will discuss about Key-Object collection, Key-Value collection, passing dynamic number of arguments to method and using eval for command processing Javascript methods/expressions of JSON sent from server.

First lets take a scenario, we require a javascript method which takes dynamic number of arguments, sends server requests, process the javascript code after successful response from server.

function SendRequest(param1,param2,...)
{
    //do something
}

Based on context, the number of parameters of SendRequest will change, for example SendRequest(param1,param2) and another might be SendRequest(param1, param2, param3, param4) . So we need to figure out a design pattern where we can achieve this requirement with out any code change when the number of parameters change (In C# we use params keyword for passing dynamic number of parameters).

First lets try to find a solution for passing dynamic number of parameters, lets make the arguments as Key – Value pair,

var params = []; //key-value collection variable
params[0] = { 'key': 'param1', 'value': 'one'};
params[1] = { 'key': 'param2', 'value': 'two'};

So lets modify our SendRequest method to take dynamic parameters,

function SendRequest(args)
{
     for (i = 0; i < args.length; i++) {
            eval(args[i].key + '=' +args[i].value);
     }
     //do something
}

And we call the method by

var params = [];
params[0] = { 'key': 'param1', 'value': 'one'};
params[1] = { 'key': 'param2', 'value': '2'};
SendRequest(params)

So when SendRequest is invoked with parameters displayed above, two javascript variable are created param1 & param2 with values ‘one’ and ‘2’, which we can use in the method to send the value to server or for evaluating any expressions.

Now lets learn how to create and use Key – Object collection and using eval to process the request. We will create a html with left area and right area div element. Our requirement is to send two asynchronous requests to server, process the response, and update the corresponding div tags with response values.

Methods to fill two div elements will be,

function changeLeftArea() {
     var clA = $('dlArea'); //div element id
     var clAH = $('dlAreaHeading'); //div element id
     type = new String('left'); //String object
     var params = []; //key-object collection variable
     params[0] = { 'key': 'clA', 'value': clA };
     params[1] = { 'key': 'clAH', 'value': clAH };
     params[2] = { 'key': 'type', 'value':  type};
     SendRequest(params);
 }
 function changeRightArea() {
     var cRA = $('drArea');//div element id
     var params = [];
     params[0] = { 'key': 'cRA', 'value': cRA };
     params[1] = { 'key': 'type', 'value': 'right' };
     SendRequest(params);
 }

Also SendRequest method is modified for working with Key – Object collection,

function SendRequest(args)
{     for (i = 0; i < args.length; i++) {
            eval(args[i].key + '=' + 'args[' + i + '].value');
     }
     var req = new Request.JSON({
         url: 'server.php?areatype=' + eval('type'),
         onComplete: function(r) { if (r != null) eval(r.s) }
     }).send();
 }

We have changed eval(args[i].key + ‘=’ + ‘args[‘ + i + ‘].value’); to assign the Object value to corresponding variable name passed. Object may be Div/table/span/any html element dom object, javascript class object, string object, it can be any thing.
For example, when changeLeftArea() is invoked, from the params collection passed we create dynamic variable clA and assigned with div html object, variable type assigned with String object, similarly others.

Next we are sending a server request to server.php which returns JSON object which will be processed using eval(r.s) in our code. This is little bit tricky and innovative method of executing client side events/commands send from server. Following is the server code (PHP) which will process our request,

<?PHP
$type = $_GET["areatype"];
if($type=="left")
	leftArea();
elseif($type=="right")
	rightArea();
else{
        //Handling unknown requests
        $scripts = "alert(r.r)";
	$json = array();
	$json['r'] = "Unknown request type!!!";
	$json['s'] = $scripts;
}
function leftArea()
{
	$responsetext = 'left Area Content';
	$responsetexth = 'left Area Heading';
	$scripts = "clA.set('html',r.r);clAH.set('html',r.h);";

	$json = array();
	$json['r'] = $responsetext;
	$json['h'] = $responsetexth;
	$json['s'] = $scripts;
	header("Content-type: application/json");
	echo json_encode($json);
}

function rightArea()
{
	$responsetext = 'right Area Content';
	$scripts = "cRA.set('html',r.r);cRA.setStyle('background-color','#eee')";

	$json = array();
	$json['r'] = $responsetext;
	$json['s'] = $scripts;
	header("Content-type: application/json");
	echo json_encode($json);
}
?>

Now let me throw a little light on purpose of eval function before sending the request and after getting the response in  SendRequest function in javascript.

  1. eval method before sending request to server
    function SendRequest(args)
    {     for (i = 0; i < args.length; i++) {
                eval(args[i].key + '=' + 'args[' + i + '].value');
         }
         var req = new Request.JSON({
             url: 'server.php?areatype=' + eval('type'),
             onComplete: function(r) { if (r != null) eval(r.s) }
         }).send();
     }

    And we call this SendRequest

    var cRA = $('drArea');//div element
    var params = [];
    params[0] = { 'key': 'cRA', 'value': cRA };
    SendRequest(params);

    So what actually the eval does here is , it creates the variable and assign the object to that variable. I this scenario our variable name we pass as key is cRA and object is $(‘drArea’).
    eval(args[i].key + ‘=’ + ‘args[‘ + i + ‘].value’) = eval (‘cRA’ + ‘=’ $(‘drArea’)
    This is dynamic creation of javascript variable and assigning an object to it.
    Why do we need to create dynamic variables here? – will be answered in with next point

  2. eval method after response from server is received
    function SendRequest(args)
    {     for (i = 0; i < args.length; i++) {
                eval(args[i].key + '=' + 'args[' + i + '].value');
         }
         var req = new Request.JSON({
             url: 'server.php?areatype=' + eval('type'),
             onComplete: function(r) { if (r != null) eval(r.s) }
         }).send();
     }

    We will call SendRequest by

    var params = [];
         params[0] = { 'key': 'cRA', 'value': cRA };
         SendRequest(params);

    And the JSON response we get from server will be,

     {"r":"right Area Content","s":"cRA.set('html',r.r);"}

    So eval(r.s) will evaluate cRA.set(‘html’,r.r), here cRA is created in Step 1 before sending the response(if Step1 code is commented cRA will be undefined) and html of div object is set with r.r value which is “right Area Content“(check above JSON).

We can now call the same SendRequest method for any server request, only the parameters differ and logic which needs to be executed after we get response can be sent from server as JSON commands as expressions.

Based on request variable type

{ 'key': 'type', 'value': 'left' };

Or

{ 'key': 'type', 'value': 'right' };

passed to server, corresponding JSON commands & text are responded back to client for further processing using eval keyword in javascript. By using this type of framework we can achieve encapsulation to a certain level, file size can be reduced (javascript code can be reduced in pages loaded initially) and code structure will be properly defined. See the demo application for details, i have used Mootools as javascript framework and PHP as server side code for demo application.

Since there are multiple takeaways in this article, Lets list out things covered,

  • Key – Value Collection.
  • Key – Object Collection.
  • Passing dynamic number of parameters in javascript function.
  • Dynamically creating and assigning javascript variable.
  • How to send JSON response from server to Client.
  • Processing server response using javascript eval keyword.
  • Command based application programming.

Have fun, do let me know your thoughts about this.
Hope this helps.

Be Sociable, Share!