1

Possible Duplicate:
How to return the response from an AJAX call from a function?

I'm trying to get some HTML content via ajax. But for some reason, though the HTML makes it to the ajax function, when I try to use it as a returned value, I get undefined.

Like this:

function get_additional_options(name) {

    var post = $.ajax({
            type: 'post',
            url: 'order_queries_templates/html/' + name + '_additional_options.php?<?=time()?>',
            //data:'product_id=' + product_id,
            dataType: 'html'

            });

    post.done(function (p) {
        console.log(p); //prints out all the HTML just as I would expect
        return p;
    });
}

but when I try to get the HTML to append it to my page like this

if (has_additional_options == "t"){
    var html_to_append = get_additional_options(name);
    console.log(html_to_append); // undefined

}

It is the same result if I use the done() method, or just return the value as a success callback. What is my error?

Community
  • 1
  • 1
1252748
  • 14,597
  • 32
  • 109
  • 229
  • it's because the ajax request is asyncronous but the function call is synchronous, however the solution is not to make the ajax request synchronous – SSH This Jan 31 '13 at 20:09
  • @Musa That is pretty identical. But I've already attempted to do two of those solutions (success callback and deferred). Can you explain how I can structure my deferred so it can work? Thank you very much. – 1252748 Jan 31 '13 at 20:14
  • You're returning the html data from the done callback which is totally different from returning from the `get_additional_options` function. If you want to return something return `post` then pass a done callback to process the html data. – Musa Jan 31 '13 at 20:20

2 Answers2

3

You can't return values from asynchronously called functions.

You should return post (i.e. the result of $.ajax) and then register a .done handler outside of your function:

function get_additional_options(name) {
    return $.ajax({
        ...
    });
};

if (has_additional_options == "t") {
     get_additional_options(name).done(function(p) {
         console.log(p);
     });
     // NB: code execution continues here immediately - don't do anything
     //     else here - all further stuff must be done in the above callback
 }
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Thanks, Alnitak. about your nota, If I wanted to do something after that first ajax request is done, how could I chain it so that they would fire in succession? Thanks again! – 1252748 Jan 31 '13 at 20:39
  • @thomas then can either be called inside the existing `.done` handler, or if they're separate functions either listed in `.done` (i.e. `.done(f1, f2, f3, ...)` or chained: `.done(f1).done(f2).done(f3)...` – Alnitak Jan 31 '13 at 20:43
  • So if get_additional_options() returns an id or something that i want to use in a subsequent ajax call, `var x = get_additional_options(name).done(ajaxFuntion2(x), ajaxFunction3(how to use what ajaxFunction2 returns here?));` Apologies if I'm making this too complicated.. – 1252748 Jan 31 '13 at 20:56
  • Take a look at `.pipe()` etc in the jQuery API manual – Alnitak Jan 31 '13 at 20:59
0

You are returning the HTML value inside the anonymous function. You're basically passing it to the post.done method.

Maybe it's better to use events in this case since you're running asynchronous code here.

function get_additional_options(name) {

    var post = $.ajax({
            type: 'post',
            url: 'order_queries_templates/html/' + name + '_additional_options.php?<?=time()?>',
            //data:'product_id=' + product_id,
            dataType: 'html'

            });

    post.done(function (p) {
        $("body").trigger("html_loaded",[p]);
    );
}

$("body").on("html_loaded", function (htmlData) {

    // Do something with your HTML data here.
    $(this).append(htmlData);

});
Robin van Baalen
  • 3,632
  • 2
  • 21
  • 35
  • deferred objects are perfectly capable of handling this without having to futz with custom events. – Alnitak Jan 31 '13 at 20:29