Wednesday, July 20, 2011

SafeCall JQuery

Often times when  programming in Javascript, you need to check to see if a function exists before calling it. so for instance if you are a asp.net programmer you might need to use sys.application.add_load(handler)

so if you were checking if that function esists you would need to do the following.


if(sys && sys.Application && typeof(sys.Application.add_load) == 'function')
{
      sys.Application.add_load(handler);
}

What this little snippet of code does is simplify that into:

$.gSafeCall(null,'sys.Application.add_load',handler);

what this function does is check if the function that is passed in is in fact a function and calls it passing in parameters from it's self to the function. it will start looking for the function Starting from window. (thus being the global calling)
the signature for this function is:

$.gSafeCall(context,handler [...] );

where the following parameters are:

context: the js object that represents this. so when you call the function and context is an object in the function this will be the object you passed in.

handler: this is a string that represents the path to the object starting from the window. the function will try to transverse to the function in question.

params: these are the optional parameters that should get passed into the function.that you are calling.

there also is a function called mSafeCall wich does the same thing but instead of starting from window it will start from the context and locate the function from the context that gets passed in. More on this in the code to follow


// Aaron Gresham Aaron@Tomrel.com
// 7/20/2011
// Function to safely call another function. checking if it exists before it calls it

// check if jquery exists.
if ($) {
 //_SafeCall the function that does all the work.
    $._SafeCall = function () {
  // Results have 2 members this is the object that gets returned by this function.
  // Value is the value returned by the function.
  // FunctionRan the value that tells the user if the function was ran or not.
        var results = { "Value": null, "FunctionRan": false };
  
  // make sure more 3 parameters were passed in.
        if (arguments.length >= 3) {
   // convert arguments into a standard array.
            var args = Array.prototype.slice.call(arguments);
   // bool that determines if it should run as global or with the context as the base.
            var runGlobal = args.shift();
   // Context in the function this will be this.
            var context = args.shift();
   // handler in the form of a string. (eg "window.alert")
            var handler = args.shift();
   // if the handler is a string run code to find the function it represents.
            if (typeof handler == 'string') {
    // split the string on it's .'s
                var partArry = handler.split('.');
    // if run global set handler to window. as starting point.
                if (runGlobal) {
                    handler = window;
     // if the first part is window that's already done. you can remove.
                    if (partArry[0] == 'window') {
                        partArry.shift();
                    }
                }
    // don't run global set the starting point to the context and start from there.
                else {
                    handler = context;
                }
    // if handler is null or you ran out of items in the part. exit while.
                while (partArry.length > 0 && handler) {
     // set handler to next object
                    handler = handler[partArry[0]];
     // Remove that part so we can use next one.
                    partArry.shift();
                }
            }
   // if handler is a function run it.
            if ($.isFunction(handler)) {
                results.Value = handler.apply(context, args);
                results.FunctionRan = true;
            }
        }
  // return your findings.
        return results;
    }
 // Global safe call
    $.gSafeCall = function () {
        var args = Array.prototype.slice.call(arguments);
  // add true to the arguments.
        args.splice(0,0,true);
  // pass it along to _SafeCall
       return $._SafeCall.apply(arguments[0], args);
    }
 // Member SafeCall
    $.mSafeCall = function () {
        var args = Array.prototype.slice.call(arguments);
  // if context is null add true (making it global) 
  // otherwise add false to it so it uses context as starting point.
        args.splice(0, 0, arguments[0] == null);
  // pass it along to _SafeCall
        return $._SafeCall.apply(arguments[0], args);
    }
}




and that's all there is to it.

No comments:

Post a Comment