Friday, January 27, 2012

If using JQuery, Careful adding Methods to Object

This was tricky one. I've been writing a JavaScript framework based on "The Teaching of Crockford". That is, no deep heirarchies, functional inheritance, etc.

One of Crockford's utilities is this:

// enables a form of "super"
Object.method ( 'superior', function ( name ) {
var that = this, method = that [ name ];
return function ( ) {
return method.apply ( that, arguments );
};
} );

This is a way of invoking a "super" method on the 'object' that you have inherited from. I don't actually use it; I just included it as a "well, I'll probably want to do that sooner or later" sort of thing (so I slapped it in a utils.js file for the time being).

My jquery ajax calls suddenly wouldn't work. I kept getting this message:

Uncaught TypeError: Object function ( name ) {
var that = this, method = that [ name ];
return function ( ) {
return method.apply ( that, arguments );
};
} has no method 'test'

Umm...wtf? So, I had to delve deeper into it...and in the unminified version of jquery, I found on line 7763, a loop that checks for the content type of the ajax response (so the call was being made, and the response returning...it was the processing of the response that was breaking).

The function is:

// Check if we're dealing with a known content-type
if ( ct ) {
for ( type in contents ) {
alert ( type + " >> " + contents [ type ] );
if ( contents[ type ] && contents[ type ].test( ct ) ) {
dataTypes.unshift( type );
break;
}
}
}

Because I had added a function "superior" to Object, "superior" now became part of the items that the response type was being tested against. It failed ("superior" did not contain a function "test", which is in the ECMAScript.js2 file, not the jquery one, click on "test" in WebStorm and you'll see). So the ajax call failed.

Solution: initially, remove the modification to Object, which I wasn't using anyway. While I understand that I could add code to JQuery to ignore this sort of thing, modifying jquery is an iffy practice, because you may have to upgrade it, etc.

A better solution would probably be to make JQuery handle the error in the event it runs into this sort of thing.

As always, thanks for visiting.

No comments:

Post a Comment