Find the jQuery Bug #7: Using a Method as an Event Handler
14 Mar 2012Introduction
In this open-ended series I’ll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.
You can view other posts in this series...
The Desired Feature
We want to use an existing object’s method to be invoked when the user clicks on a button.
The Buggy Code
The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?
You can view, run, and edit the above code sample from the following embedded jsFiddle.
The result that we expected was to see was an alert box showing up when the user clicks the Register button, but instead the following error shows up in the console.
The Underlying Problem
At the root of the problem is that once the event handler is invoked jQuery makes sure the this
pseudo parameter is set to the DOM element that caused the event.
Inside of the conference.register
method listed above, the this
parameter refers to the register button DOM element. Since this
is a DOM element that is why we are getting the “Cannot call method ‘push’ of undefined” error.
What we need to resolve this issue is a way to control the value of the this
parameter when the conference.register
method is invoked. Thankfully, there is a way in jQuery to do this.
A Solution
The solution to fix this problem is really simple and straightforward. As of version 1.4, jQuery added the $.proxy()
method to help solve the bug found in the previous example.
jQuery.proxy( function, context )
Returns: FunctionTakes a function and returns a new one that will always have a particular context. -- http://api.jquery.com/jQuery.proxy/
In order to fix our example we just need to wrap the conference.register
method with the $.proxy()
method and provide the context that we want the pseudo this
parameter to represent.
You can view, run, and edit the above code sample from JSBin.
If you test out the code again below you’ll notice that once you’ve filled in the textbox and click enter then the behavior will continue as we expected.
Alternate Solutions
The above solution shows how you can use the $.proxy()
method to solve the problem, but technically you could have used a plain JavaScript technique instead. By using the .call()
or .apply()
methods in JavaScript you can control what the value of the this
parameter will be just like we did with the $.proxy()
method.
The following code snippet shows how you can use the .call()
method to control the this
parameter.
In a very similar way the next snippet of code shows how you can use the .apply()
method as an alternate solution.
NOTE: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments. -- https://developer.mozilla.org/...
You can view, run, and edit the above code sample from jsFiddle.
Conclusion
The key concept to remember here is that if you ever need to control the value of the pseudo this
paramater inside an event handlers, then you can use the $.proxy()
method in jQuery. In addition, you could just use the .call()
or .apply()
methods in JavaScript if you would rather not use the $.proxy()
method.
Until next time…