[Proto-Scripty] Re: Named functions in onComplete not waiting for completion

2009-04-15 Thread Diodeus

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

2009-04-15 Thread T.J. Crowder

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

2009-04-15 Thread Szymon Wilkołazki

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

2009-04-15 Thread Diodeus

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

2009-04-14 Thread T.J. Crowder

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
-~--~~~~--~~--~--~---