Avoid this tricky conflict between ASP.NET AJAX and jQuery

ASP.NET and jQuery's logos togetherYou have probably already read the great news that Microsoft is going to begin shipping jQuery with Visual Studio and ASP.NET MVC. If not, make sure you take a minute to read the official announcements from both ScottGu and John Resig. This represents a surprising, yet tremendously welcomed change of course for Microsoft.

If you haven’t yet used jQuery with ASP.NET, you’re in for a pleasant surprise. It removes almost all of the pain from client-side development. Coming from an ASP.NET centric perspective, you may find several of my previous jQuery articles useful.

Additionally, I highly recommend the articles that Matt Berseth and Rick Strahl have written on the topic of using jQuery with ASP.NET. I am constantly amazed at the quantity and quality of content that they both generate.

Introductions aside, I’d like to take this opportunity to discuss an incompatibility between ASP.NET AJAX and at least one jQuery plugin, which needs to be fixed.

A simple combination leads to an odd problem

Last month, I came across someone having an odd problem with ASP.NET AJAX and jQuery, on the ASP.NET forums. While using the jDrawer plugin to jQuery, he found that adding an ASP.NET AJAX ScriptManager completely broke jDrawer.

Having never encountered trouble mixing ASP.NET AJAX and jQuery plugins, I was reluctant to place the blame on ASP.NET AJAX until I tried it for myself. However, the problem was readily reproducible by downloading the jDrawer sample and adding a ScriptManager. It immediately went from a working demo to throwing this JavaScript error:

arguments[i] is undefined

Inspecting the specified section of the jDrawer code revealed this function:

PreloadImages: function() {   for (var i in arguments.length)     if (arguments[i].type === "array")       for (var j in arguments[i])         // Irrelevant image preloading code.   else     // Irrelevant image preloading code. },

It looks simple enough, but we have a problem here…

Understanding the problem

In JavaScript, every function call is accompanied by a special arguments property which consists of an array of any parameters that the function was called with. This allows for functions with a variable number of parameters, like String.format.

jDrawer’s PreloadImages function is dependent on this arguments property. The property is necessary so that an arbitrary number of image URLs may be passed in for preloading. Unfortunately, the plugin author didn’t quite get the for loop right. He’s using the associative form (foreach), but arguments.length is a Number, not an array.

As I’ve previously covered, one of the nice things that ASP.NET AJAX brings to the table is an assortment of upgrades to JavaScript’s base types. Among them, the Number type is modified to include a format property, the root of this trouble:

Using Firebug to debug the jDrawer JavaScript error

Notice that even though the arguments property is an empty array, execution has entered the for loop. The reason for that? The jDrawer code is attempting to iterate over the Number, arguments.length, not the empty array itself.

Normally, this would cause the function to silently abort, since the base Number type has nothing to iterate over. However, ASP.NET AJAX has added a few features to the Number type, giving the faulty code the extended Number type’s properties to iterate over.

Because those certainly aren’t valid keys for the arguments array, execution always fails when line 424 tries to reference arguments[i] for the first time. Basically, it’s attempting to access arguments[‘format’], which throws the error.

The solution is easy!

The solution is to iterate over the arguments array using a traditional for loop:

PreloadImages: function() {   for(var i = 0; i++; i < arguments.length)     if (arguments[i].type === "array")       for (var j in arguments[i])         // Irrelevant image preloading code.   else     // Irrelevant image preloading code. },

The troublesome format key is ignored, and the function operates as desired.

As a bonus, fixing the error also fixes the image preloading. Even though it wasn’t causing an error without a ScriptManager on the page, the preloading code in this plugin was never working before.

Conclusion

Don’t get me wrong — nothing this minor could possibly begin to dampen my excitement over jQuery getting this official nod from Microsoft.

However, with today’s news about official jQuery support and Microsoft’s efforts toward peaceful client-side coexistence in general, I think this issue is something that should be addressed if at all possible.

It’s not the ScriptManager’s fault that this happened, but it isn’t a problem unless the ScriptManager is present. Not many developers are going to track down obscure JavaScript errors caused by two third party pieces of code. They’ll see the cause of adding the ScriptManager, the effect of it breaking the page, and logically lay the blame on the ScriptManager (unfairly).

Hopefully, having the problem and solution identified here will mean that anyone who runs into it in the meantime will be able to fix it with a quick Google search.

As mentioned previously, I have several posts on using jQuery with ASP.NET AJAX that may be helpful if you’re just getting started with the combination.

If the topic interests you, be sure that you’re subscribed to Encosia updates via either my RSS feed or its email-based counterpart. More posts on ASP.NET and jQuery are on the way soon.

###

Originally posted at Encosia.com. If you’re reading this on another site, come on over and take a look at the real thing.

Avoid this tricky conflict between ASP.NET AJAX and jQuery

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

WP Like Button Plugin by Free WordPress Templates