Reputation: 921
I'm using jQuery and flot in chrome and firefox. As I work on my code, I find that execution silently fails on stupid stuff like accessing non-existent hash structures and the like.
It feels like there is some try {} catch {} logic within jQuery that keeps me from seeing any errors.
Any pointers on how to get around this without blanket hack-n-slash to isolate where a simple bug is?
jshint hasn't been too helpful.
--edit--
more debugging shows a trend.
I'm basically finding typos (undefined variables) and premature fetching of object properties before they exist. Using .hasOwnProperty() has helped but is cumbersome. I think I saw a handy utility someplace to help test deep structures succinctly.
Upvotes: 5
Views: 529
Reputation: 108490
.length
is your friend when debugging jQuery. Because even if:
document.getElementById('nonexistent');
will return null
in JavaScript, using a jQuery selector will return an object and cast true
:
if(!document.getElementById('nonexistent')) {
alert('not here!');
}
if(!$('#nonexistent')) {
alert('here, here!');
}
Which means that:
$('#nonexistent').doSomething().doSomethingElse().whatever();
Will probably not throw errors, so you will have a hard time knowing what "didn’t work" in the chain.
However, checking the object length works:
if(!$('#nonexistent').length) {
alert('not here!');
}
jQuery is designed to fail silently, since one of it’s core use cases is chaining. And if selectors or prototype methods would return null or false in the chain, using jQuery would throw null-reference errors more often than most inexperienced programmers would want.
Update
You can probably do your own debugging by modifying the prototypes if in debug mode. I tried this:
var debug = ['hide','show'], // Array of jQuery methods to debug
i = 0, name;
for(; debug[i]; i++) {
name = debug[i];
if (typeof $.fn[name] == 'function') {
$.fn[name] = (function(name, fn) {
return function() {
if ( !this.length ) {
console.warn('No elements selected when calling '+name);
}
fn.apply(this, Array.prototype.slice.call( arguments ));
};
}(name, $.fn[name]));
}
}
Now, whenever I call 'hide', it will warn me if there are no elements in the chain:
$('#nonexistent').hide(); // consoles a warning
Fiddle: http://jsfiddle.net/B4XQx/
Upvotes: 3
Reputation: 12545
there's the workaround here:
but I doubt that's really what you want-
Upvotes: 0