ericslaw
ericslaw

Reputation: 921

jquery hides simple javascript errors

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

Answers (2)

David Hellsing
David Hellsing

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

chrismarx
chrismarx

Reputation: 12545

there's the workaround here:

jQuery error on null selector

but I doubt that's really what you want-

Upvotes: 0

Related Questions