Dani
Dani

Reputation: 4111

Error in Javascript return

I want to receive HTML code in chat.openChat() from chat.getHtmlPage() but return operation is "undefined".

var chat = {
    openChat : function($url){
        $('#popup').html(chat.getHtmlPage($url)); // It's wrong, UNDEFINED.
    },

    getHtmlPage : function($url){
        $.ajax({
            url: $url
        }).done(function($html) { 
            return $html; // It's OK! $html is with correct html, see with alert().
        });
    }
}

$(document).ready(function(){
    $('.btnChat').click(function(){
        chat.openChat($(this).attr('href')); // It's OK!
        ...
        return false;
    });
});

Upvotes: 0

Views: 858

Answers (5)

Dani
Dani

Reputation: 4111

SOLUTION

To do one general function (original idea).

var chat = {

    openChat : function($url, $htmlElement){

        chat.setHtmlPage($url, $htmlElement);
    },


    setHtmlPage : function($url, $htmlElement){

        $.ajax({
            url: $url
        }).done(function($html) { 
            $($htmlElement).html($html);
        });
    }

}

$(document).ready(function(){

    $('.btnChat').click(function(){

        chat.openChat($(this).attr('href'), '#popup');

        ...

        return false;
    });

});

Upvotes: 0

KeyNone
KeyNone

Reputation: 9150

The first 'A' in AJAX is 'Asynchronous', this means: by the time the .done() gets called, the rest of your code already moved on. With this knowledge, a return in .done() simply makes no sense.
Instead, we just deactiveate the asynchronous behaviour of AJAX, setting async: false in the .ajax-object. But be aware that this is not the original purpose of AJAX and it may cause trouble in some browsers.

Oone solution would then be to set the return into your getHtmlPage (in addtion to setting async to false!):

getHtmlPage : function($url){

    //a new variable to store the ajax-result
    //defining it here, so it's only visible within the scope of getHtmlPage
    var html;

    $.ajax({
        url: $url,
        async: false
    }).done(function($html) {
        //we use the html variable here to store the result 
        html = $html;
    });

    //finally returning the variable
    return html;
}

This way, your return statement won't be executed until the ajax-call finishes.

Upvotes: 0

Krzysztof
Krzysztof

Reputation: 16130

By default AJAX request is asynchronous, so it ends after you get result from getHtmlPage. Even if you change it to be synchronous, you will still have undefined in openChat, because you return value from done handler, not from getHtmlPage.

You should provide a callback to getHtmlPage method. Example:

var chat = {
    openChat : function($url){
        chat.getHtmlPage($url, function(html) {
            $('#popup').html(html); 
        });
    },
    getHtmlPage : function($url, callback){
        $.ajax({
            url: $url
        }).done(callback);
    }
}

Upvotes: 4

Martin
Martin

Reputation: 1508

Ajax calls are asynchronously, that's why you can't use the return of the ajax function immediately. to store the result in $('popup').

You will have to do something like this:

openChat : function($url){

    chat.getHtmlPage($url));
},

setHtmlPage : function ($html) {
    $('popup').html($html);
},


getHtmlPage : function($url){

    $.ajax({
        url: $url
    }).done(function($html) { 
        chat.setHtmlPage($html);
    });
}

You may also want to have a look to the jquery documentation about ajax. There is a way to make ajax requests synchronously, but that will block your browser and it's deprecated in the newer versions. (and it's not really ajax after all)

Check the part about async

Upvotes: 3

Viktor S.
Viktor S.

Reputation: 12815

It should be like this:

var chat = {
    openChat : function($url){
        chat.getHtmlPage($url);
    },

    getHtmlPage : function($url){
        $.ajax({
            url: $url
        }).done(function($html) { 
            $('#popup').html($html); 
        });
    }
}

$(document).ready(function(){
    $('.btnChat').click(function(){
        chat.openChat($(this).attr('href')); // It's OK!
        ...
        return false;
    });
});

AJAX is asynchronouse. Once you call it, script exection goes to next line and .done is called later, after request is finished. Also, return from done will do nothing. As it's jquery ajax event triggered after request is done. And jquery will not pass returned value to upper level of code even if you will make it work in synchronouse way.

Upvotes: 2

Related Questions