-
Get a monthly update on best practices for delivering successful software.
If you're using prototype (or rails, which uses prototype by default), you've probably seen this javascript error before:
handler is undefined
While not particularly threatening (no ill side effects seem to occur), the error causes a lot of noise and, quite frankly, is pretty annoying. Fortunately, there is a quick and painless patch to keep your error log free from this bane.
The problem occurs in the Event class defined by prototype. In the function createWrapper, there is a single line that causes the error.
handler.call(element, event);
The problem seems to be intermittent, but I get it fairly reliably when observing the "dom:loaded" event to automatically focus a text field on a page. I also see it reliably when observing the "load" event on a window to do the same thing. This leads me to believe there may be something going on with event handling at that level (although, this is just speculation).
In order to prevent this error we can use the old "undefined" trick to guard the line. While using a try block would work, that has the possibility for hiding all exceptions-- even the "valid" ones. For this reason I don't recommend using a try block. It should also be noted that trying to guard the line with a simple if (handler) does not work.
if (typeof handler != 'undefined') {
handler.call(element, event);
}
This will prevent the error from occurring and not negatively affect the code in the process. While it doesn't technically fix the root cause of the issue (why is the handler undefined?), it will at least prevent your site from causing errors on every page.
The complete function looks like this:
function createWrapper(element, eventName, handler) {
var id = getEventID(element);
var c = getWrappersForEventName(id, eventName);
if (c.pluck("handler").include(handler)) return false;
var wrapper = function(event) {
if (!Event || !Event.extend ||
(event.eventName && event.eventName != eventName))
return false;
Event.extend(event);
if (typeof handler != 'undefined') {
handler.call(element, event);
}
};
Related posts:
Topics: Javascript, Prototype
Thank you! This indeed prevents the ‘handler is undefined’ error from showing up. I use Prototype a lot to observe dom:loaded and never understood where this error came from.
Comment by Sander, Tuesday, January 27, 2009 @ 5:46 pm
Thanxs a lot – it helped!
Comment by BugFix, Sunday, February 8, 2009 @ 12:27 am
thanks for info
my first thought was it is me doing something wrong with prototype Event.observe
Comment by Quleczka, Sunday, March 1, 2009 @ 7:05 am
Thanks for the solution.
It takes care of error.
Comment by Srikant, Friday, March 6, 2009 @ 12:49 pm
Thank you for publishing this fix , I’m glad you were as annoyed as I was with this error
Comment by Tyche, Saturday, March 7, 2009 @ 10:19 am
The problem arises when the handler parameter to Event.observe is undefined. The likely cause of your error is the following.
// Wrong. Passing result of callback function.
Event.observe(window, “load”, the_callback());
In the example above, the_callback() is being executed as you are making the Event.observe() call. That means the _result_ of the_callback() is being passed as the “handler” parameter of Event.observe().
// Correct. Passing name of callback function.
Event.observe(window, “load”, the_callback);
In this case, you are passing the _name_ of the function to the “handler” parameter of Event.observe().
Comment by Daniel Convissor, Tuesday, March 10, 2009 @ 10:22 am
Hi Daniel Convissor.
And if the calback function needs a parameter to be executed?
How can I pass this parameter to the calback or in this case it’s not necessary?
Comment by Bruno Lacerda, Tuesday, June 9, 2009 @ 6:03 am
I have the same question. How can I pass a parameter to the callback function? If i do, the handler becomes undefined.
Thanks in advance!
Comment by juanjo, Monday, July 6, 2009 @ 4:15 am
document.observe(’dom:loaded’, function(){test(’hi’)});
Seems to work ok when parameters are needed in the callback
Comment by Pums, Saturday, July 11, 2009 @ 4:09 am