1. #1
    Ext User 72's Avatar
    Join Date
    Apr 2007
    Location
    Czech republic, EU
    Posts
    152
    Vote Rating
    0
    72 is on a distinguished road

      0  

    Default Process method result before it is passed

    Process method result before it is passed


    Whole today (yesterday) i spent time to get intercepted some functions to manipulate responses and no way. Now i modify createSequence to pass result instead of func params. I dont have to say that the edit (passing by reference) works only on passed objects. I cannot find any other way to get processed and modify all requstest in only one function. Maybe this is dirty (i cant judge it) but it works great.

    Code:
    				Ext.apply(Function.prototype, {
    				    processResult : function(fcn, scope){
    				        if(typeof fcn != "function"){
    				            return this;
    				        }
    				        var method = this;
    				        return function() {
    							var retval = method.apply(this || window, arguments);
    							fcn.apply(scope || this || window, [retval]);
    							return retval;
    				        };
    				    }
    				});
    Typical usage i found is in processing all responds for login functionality for example

    Code:
    				YAHOO.util.Connect.createResponseObject = YAHOO.util.Connect.createResponseObject.processResult( function( result ) {
    					var resp = Ext.decode(result.responseText);
    					// Some response manipulation, i can change responseText here, delete or add some stuff
    					// This sample expects JSON data only (Ext.decode, Ext.encode)
    					result.responseText = Ext.encode(resp);
    				});
    Inside of this object pass all async request functions (grids, updateManagers, contentPanels, direct Ext.lib.Ajax.request, etc.), so it can be easily handled and whats great that it is written only one time..

    Hope it helps to anyone, drop a line if you find it useful.
    72

  2. #2
    jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    Frederick MD, NYC, DC
    Posts
    16,353
    Vote Rating
    77
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    I hope to some day fully understand what you're doing and code like this. I'm reading as much as i can

  3. #3
    Ext User haibijon's Avatar
    Join Date
    Mar 2007
    Posts
    105
    Vote Rating
    0
    haibijon is on a distinguished road

      0  

    Thumbs up


    Your solution seems to work pretty well, though it doesn't really make sense to attach a processResult method to the Function prototype unless it is used/useful for all funcitons. Been looking to do something very similar, to handle user session timeout messages etc in headers on the global level (all requests, ie coming from an Ext.tree or Ext.form etc).

    I think it would probably be better if Ext implemented Ext.lib.Ajax as an observable so we could set something like Ext.lib.Ajax.on('requestComplete', func, scope); and catch/modify all ajax requests responses...

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,496
    Vote Rating
    44
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    No, that makes all kinds of sense! The prototype object of Function is where all functions get their properties.

    Nice idea 72! I think you should submit a feature request with this code for inclusion in Ext.

    I think it could be quite a useful pattern to put your own code in to massage the result object from a function before that function's caller sees it.

    dj, those Function extensions look weird, but if you read the code enough times, they make sense.

    Essentially, what is happening is that we're createing a new function which wraps the original function. That's the basis of all the Function extensions in Ext.

    Create a new function which calls the original function, and the function specified.

    It's well worth while for your javascript programming to ponder over that code until you understand it.

  5. #5
    Ext User 72's Avatar
    Join Date
    Apr 2007
    Location
    Czech republic, EU
    Posts
    152
    Vote Rating
    0
    72 is on a distinguished road

      0  

    Wink


    Thanks Animal, good to hear from expert such as you are. Im using it for checking authorization on every request response but may be useful in any other function where we want to modify or check its result.

    Exactly like you said (wrote)

    This function is exactly like createSequence() with one difference only. Parameter is passed method result instead of original method arguments.

    I tried to override (make new function definition) original createSequence function but i cant get the way how to pass result along with original parameters, so define new function wrap was the easiest way for me.

    If some people finds it useful so feel free to make Feature request for next rev of Ext.
    72

  6. #6
    Ext User haibijon's Avatar
    Join Date
    Mar 2007
    Posts
    105
    Vote Rating
    0
    haibijon is on a distinguished road

      0  

    Default


    Quote Originally Posted by 72 View Post
    If some people finds it useful so feel free to make Feature request for next rev of Ext.
    I think it's great, already using it to check for exceptions/timeouts hope it makes it, and again thanks for this I know alot of us have been trying to find a global way of catching request responses like this!

  7. #7
    Ext User 72's Avatar
    Join Date
    Apr 2007
    Location
    Czech republic, EU
    Posts
    152
    Vote Rating
    0
    72 is on a distinguished road

      0  

    Default


    Quote Originally Posted by haibijon View Post
    ..I know alot of us have been trying to find a global way of catching request responses like this!
    No prob man im really happy if its useful for anyone..enjoy
    72

  8. #8
    Ext User burn's Avatar
    Join Date
    Mar 2007
    Location
    Italy
    Posts
    69
    Vote Rating
    0
    burn is on a distinguished road

      0  

    Default


    KUDOS!!!!!

    I can't even begin to understand the syntax here:

    Code:
    var retval = method.apply(this || window, arguments);
    fcn.apply(scope || this || window, [retval]);
    But what it does is crystal clear and it's so darn useful... You really made my day, I already had a handful of situations in which this would have allowed me to go on a certain logic path instead of refactoring my code either server side or client side!

  9. #9
    Ext User 72's Avatar
    Join Date
    Apr 2007
    Location
    Czech republic, EU
    Posts
    152
    Vote Rating
    0
    72 is on a distinguished road

      0  

    Default


    Quote Originally Posted by burn View Post
    ..can't even begin to understand the syntax
    First row run original function and get its result to retval var. this||window means scope (its tha almost same if you run this.blabla() or window.blabla()), so if this is defined will be used, if not window will be used, arguments is a local variable defined in every function by javascript itself

    Second row applies scope (so again this scope(if defined)||this||window) and run processResult function with retval parameter (we get it in func before). If in processResult pinned method will be retval changed it will be changed in func return also.

    BEWARE: Cause of javascript dont know passing values by reference so it will be changed if retval is an object only.

    Got it? Its easy..
    72

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,496
    Vote Rating
    44
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    It could be that createSequence could be refactored to allow this. Below, if you pass an extra param as true, it will return the return value of your sequence function (having passed the return value from the original at the end of the argument list)

    Code:
        createSequence : function(fcn, scope, returnSeqRetval){
            if(typeof fcn != "function"){
                return this;
            }
            var method = this;
            return function() {
                var retval = method.apply(this || window, arguments);
                var seqRetval = fcn.apply(scope || this || window, arguments.concat(retval));
                return returnSeqRetval ? seqRetval  : retval;
            };
        },
    Jack, are you on this thread? What do you think?