[Proto-Scripty] Re: Named functions in onComplete not waiting for completion
Thanks for the tips T.J. Curry was been around a lot longer than Prototype. Yep, it's a strange name. see: http://en.wikipedia.org/wiki/Currying On Apr 15, 10:21 am, "T.J. Crowder" wrote: > Hi, > > > In another situation, I need to pass parameters to the callback. So > > would I do it this way? > > > var temp = handleCompletion(5) > > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); > > You're calling the function immediately again. This line: > > > var temp = handleCompletion(5) > > ...calls the function handleCompletion with the argument 5 and assigns > the result of the function to the variable temp. That's probably not > what you meant to do! :-) > > What you want is a reference for a function that, when called, will > call handleCompletion with the value 5. The generic way to do that is > to use your own function for it: > > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', function() { > handleCompletion(5); > }); > > But this is such a common thing to want to do that Prototype provides > a mechanism for doing it: Function#curry[1]. (I have no idea who > thought "curry" was a good name for this, but it's not the Prototype > developers' fault, they just used a term that was already being used > elsewhere.) Using Function#curry: > > var temp = handleCompletion.curry(5); > wrapAjaxUpdater( > 'showsomething.php?id=5', > 'somediv', > temp > ); > > ...or just: > > wrapAjaxUpdater( > 'showsomething.php?id=5', > 'somediv', > handleCompletion.curry(5) > ); > > If you want to do that with a function where you *also* want to set > its context (the "this" value that will be in effect when the function > is called), use Function#bind[2] instead: > > wrapAjaxUpdater( > 'showsomething.php?id=5', > 'somediv', > handleCompletion.bind(desiredContext, 5) > ); > > In addition to simplicity and convenience, using curry() and bind() > means you don't create a closure in the current context (you create a > closure in a different context, but it's a pretty thin one so the > overhead is minimal), which can be useful sometimes. For more about > closures, I wrote up a couple of blog entires on them a while back.[3] > [4] > > [1]http://prototypejs.org/api/function/curry > [2]http://prototypejs.org/api/function/bind > [3]http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html > [4]http://blog.niftysnippets.org/2008/03/closures-by-example.html > > > BTW, it's OT, but I get the impression you're not very experienced in > JavaScript yet, so: FWIW , I noticed in your code examples that you > frequently leave off semicolons at the ends of lines, e.g.: > > > var temp = handleCompletion(5) > > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); > > (There are three missing from your earlier exFetch function as well.) > That really should be: > > > var temp = handleCompletion(5); > > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); > > (Note the semicolon at the end of the first line.) It's perfectly > valid syntax to leave off that semicolon, it's part of the JavaScript > specification that the interpreter will automatically insert it for > you in places where it thinks you meant to have one. But it's an > extremely bad idea and arguably the worst "feature" in JavaScript. > Never rely on semicolon insertion, *always* include them yourself. > Not only does it make your intent clearer to those who read your code, > but it means that if you use minifiers and such (and who doesn't?), > your code will still work. Many minifiers will remove line breaks, > which means your code above would become: > > > var temp = handleCompletion(5) wrapAjaxUpdater('showsomething.php?id=5', > > 'somediv', temp); > > ...which is *not* valid syntax and will cause an error. If the > semicolon were there: > > > var temp = handleCompletion(5); wrapAjaxUpdater('showsomething.php?id=5', > > 'somediv', temp); > > It would still work. Just FWIW. Some minifiers are better at > preserving necessary line breaks than others, but barring writing a > full JavaScript parser (most of these are regex-based), they're going > to get it wrong some of the time... > ;-) > > HTH, > -- > T.J. Crowder > tj / crowder software / com > Independent Software Engineer, consulting services available > > On Apr 15, 2:26 pm, Diodeus wrote: > > > Yes, I understand what you've said. I was making it more convoluted > > than need be. > > > wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion); - > > works correctly > > > wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion()); - > > does not work because I'm calling the function, not passing a > > reference to it. > > > In another situation, I need to pass parameters to the callback. So > > would I do it this way? > > > var temp = handleCompletion(5) > > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); --~--~-~--~~
[Proto-Scripty] Re: Named functions in onComplete not waiting for completion
Hi, > In another situation, I need to pass parameters to the callback. So > would I do it this way? > > var temp = handleCompletion(5) > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); You're calling the function immediately again. This line: > var temp = handleCompletion(5) ...calls the function handleCompletion with the argument 5 and assigns the result of the function to the variable temp. That's probably not what you meant to do! :-) What you want is a reference for a function that, when called, will call handleCompletion with the value 5. The generic way to do that is to use your own function for it: wrapAjaxUpdater('showsomething.php?id=5', 'somediv', function() { handleCompletion(5); }); But this is such a common thing to want to do that Prototype provides a mechanism for doing it: Function#curry[1]. (I have no idea who thought "curry" was a good name for this, but it's not the Prototype developers' fault, they just used a term that was already being used elsewhere.) Using Function#curry: var temp = handleCompletion.curry(5); wrapAjaxUpdater( 'showsomething.php?id=5', 'somediv', temp ); ...or just: wrapAjaxUpdater( 'showsomething.php?id=5', 'somediv', handleCompletion.curry(5) ); If you want to do that with a function where you *also* want to set its context (the "this" value that will be in effect when the function is called), use Function#bind[2] instead: wrapAjaxUpdater( 'showsomething.php?id=5', 'somediv', handleCompletion.bind(desiredContext, 5) ); In addition to simplicity and convenience, using curry() and bind() means you don't create a closure in the current context (you create a closure in a different context, but it's a pretty thin one so the overhead is minimal), which can be useful sometimes. For more about closures, I wrote up a couple of blog entires on them a while back.[3] [4] [1] http://prototypejs.org/api/function/curry [2] http://prototypejs.org/api/function/bind [3] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html [4] http://blog.niftysnippets.org/2008/03/closures-by-example.html BTW, it's OT, but I get the impression you're not very experienced in JavaScript yet, so: FWIW , I noticed in your code examples that you frequently leave off semicolons at the ends of lines, e.g.: > var temp = handleCompletion(5) > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); (There are three missing from your earlier exFetch function as well.) That really should be: > var temp = handleCompletion(5); > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); (Note the semicolon at the end of the first line.) It's perfectly valid syntax to leave off that semicolon, it's part of the JavaScript specification that the interpreter will automatically insert it for you in places where it thinks you meant to have one. But it's an extremely bad idea and arguably the worst "feature" in JavaScript. Never rely on semicolon insertion, *always* include them yourself. Not only does it make your intent clearer to those who read your code, but it means that if you use minifiers and such (and who doesn't?), your code will still work. Many minifiers will remove line breaks, which means your code above would become: > var temp = handleCompletion(5) wrapAjaxUpdater('showsomething.php?id=5', > 'somediv', temp); ...which is *not* valid syntax and will cause an error. If the semicolon were there: > var temp = handleCompletion(5); wrapAjaxUpdater('showsomething.php?id=5', > 'somediv', temp); It would still work. Just FWIW. Some minifiers are better at preserving necessary line breaks than others, but barring writing a full JavaScript parser (most of these are regex-based), they're going to get it wrong some of the time... ;-) HTH, -- T.J. Crowder tj / crowder software / com Independent Software Engineer, consulting services available On Apr 15, 2:26 pm, Diodeus wrote: > Yes, I understand what you've said. I was making it more convoluted > than need be. > > wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion); - > works correctly > > wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion()); - > does not work because I'm calling the function, not passing a > reference to it. > > In another situation, I need to pass parameters to the callback. So > would I do it this way? > > var temp = handleCompletion(5) > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculou
[Proto-Scripty] Re: Named functions in onComplete not waiting for completion
Diodeus wrote: [...] > In another situation, I need to pass parameters to the callback. So > would I do it this way? > > var temp = handleCompletion(5) > wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); > That still is not correct. This would assign the *result* of the handleCompletion function to the temp variable. What you need here is to curry[1] the function with parameters. var temp = handleCompletion.curry(5); wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp) //or in one (almost) line: wrapAjaxUpdater('showsomething.php?id=5', 'somediv', handleCompletion.curry(5)); Please read the docs of curry[1]. It is worth to at least skim through the whole api docs of prototype.js. [1] http://prototypejs.org/api/function/curry -- Best Regards SWilk --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Named functions in onComplete not waiting for completion
Yes, I understand what you've said. I was making it more convoluted than need be. wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion); - works correctly wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion()); - does not work because I'm calling the function, not passing a reference to it. In another situation, I need to pass parameters to the callback. So would I do it this way? var temp = handleCompletion(5) wrapAjaxUpdater('showsomething.php?id=5', 'somediv', temp); --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Named functions in onComplete not waiting for completion
Hi, My guess is the problem lies in your code that calls exFetch (or at least code elsewhere), since that quoted code not only doesn't call the handler right away, it won't call it _at all_. This anonymous function: function (transport) { window[callBack] } ...doesn't call the handler. It looks up a property name on the window object (and presumably gets back a function reference), and then throws away the result. To call the function, you'd have to put () after the expression that gives you the function reference (or use call(), apply(), etc.). So this _defines_ a function: x = function() { ... }; ...and this _refers_ to the function without calling it (no parens or the like), assigning the function reference to 'y': y = x; This _calls_ it, assigning the function's *result* to 'z': z = x(); > Since the callback could be any function, I'm > passing the callback function as a string and calling it via window > [callBack]... If that's your only reason for passing around the function name as a string (that it could be any function), you don't gain anything by doing that. Functions are first class objects, so you can pass them by reference -- you do it all the time, if you use any of Prototype's Ajax wrappers, or Enumerable#each, or any of several other bits of Prototype. In fact, you did it in the quoted code, with the anonymous function. Here's a function that accepts a callback and uses it as the onComplete handler of an Ajax.Updater call: function wrapAjaxUpdater(url, element, callback) { new Ajax.Updater(url, element, { onComplete: callback }); } (It also has the advantage of not creating a further closure.) An example of calling it: wrapAjaxUpdater('showsomething.php', 'somediv', function (transport) { alert('It finished!'); }); Or call it with a named handler (note the absense of parens after the handler's name): wrapAjaxUpdater('showsomething.php', 'somediv', handleCompletion); ...where handleCompletion is defined somewhere and can be reused: function handleCompletion(transport) { alert('It finished!'); } HTH, -- T.J. Crowder tj / crowder software / com Independent Software Engineer, consulting services available On Apr 14, 10:44 pm, Diodeus wrote: > Here is my function. It is a general purpose wrapper for various AJAX > call in my program. Since the callback could be any function, I'm > passing the callback function as a string and calling it via window > [callBack], which kinda of works except it's not waiting for the > actual AJAX call to complete - it fires right away. Since I wrapped > the callback in an anonymous function, I would have expected the > execution to be deferred, but it isn't. > > Where have I gone wrong? > > function exFetch(url,element,callBack) { > now = new Date() //break cache > //$('lastAjax').innerHTML = url +"|"+element > new Ajax.Updater(element, url+'&_UserReference='+key+'&now='+now, > {method:'get',evalScripts:true,onComplete:function(transport) { > window[callBack] > } > }); > > } > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---