Antonio Laguna
Antonio Laguna

Reputation: 9282

Object out of scope in deferred?

I'm making some tests to try to learn a little bit more about deferreds. So, I made an ajax web navigation:

$('ul#nav a').on('click', function(e){          
    var hash = $(this).attr('href');
    check(hash).fail(function(){
        e.preventDefault();
    });
});
function check(hash){
    var deferred = $.Deferred();
    if (!hash) {                
        hash = window.location.hash;
    }
    if (!hash) {
        var url = window.location.pathname;
        var file = url.substring(url.lastIndexOf('/')+1);
        hash = file.replace(extension,'');
    }
    if (hash !== prev_url){
        prev_url= hash;
        loadPage(hash).done(
            function(data){ 
                var html = $(data);
                var filtered= html.find('#content');
                content.html(filtrado.html());
                deferred.resolve();
            }
        ).fail(function(){ // Url doesn't exist
            content.html('<p>Page does not exist!</p>');
            deferred.reject();                  
        });
    }
    return deferred;
}

Everything seems to be working fine except the check.fail function has no access to the event object so I'm unable to prevent the page change and so, it fails.

Upvotes: 0

Views: 188

Answers (1)

Gary Green
Gary Green

Reputation: 22395

The fail callback closes over e (it is a closure) so it definitely should have access (or do you get an error?).

The problem is likely that at the moment the fail callback is executed (some time later as you are doing an Ajax request, which is asynchronous), the event handling is already completed. Calling e.preventDefault() does not have any effect anymore.


You need to do e.preventDefault(); straight after the click and assume the page doesn't exist until the asynchronous Deferred events tell you otherwise.

$('ul#nav a').on('click', function(e){
    e.preventDefault();  // Assume bad link until otherwise proven
    var hash = $(this).attr('href');
    check(hash).done(function(){
       window.location.href = hash; // Good hash, let's go to that
    });
});

Upvotes: 3

Related Questions