-1

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;
    });
});
1
  • AJAX is asynchronous. You have to wait for it te request to complete to get its return value. As it is, your callback doesn't even return from the containing function: it merely returns from the callback, doing nothing. You should let your custom AJAX function take a callback of its own to call once it has the necessary data. Commented Nov 20, 2012 at 11:47

5 Answers 5

4

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);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Good idea. I like this. Thank you.
This is probably the most clean way indeed.
3

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

Comments

2

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.

1 Comment

Yes, this two solution (same really) i want. But i want construct one GENERAL function, but this is impossible with async... Pain for me.
0

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.

2 Comments

As far as I know it will still be returned (nulL) before the ajax is ready in this way.
As far as i know it will wait for the ajax call to finish, as I make it synchronous with async: false - will test it when I get the time to do so.
0

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;
    });

});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.