Question

I'm trying to call a function that contains jQuery code. I want this function to return the results of the jQuery statement. It is not working, and I'm trying to figure out why.

function showGetResult (name) {
    var scriptURL = "somefile.php?name=" + name;
    return $.get(scriptURL, {}, function(data) { return data; });
}

alert (showGetResult("John"));

The alert displays "[object XMLHttpRequest]." However, if I run the jQuery statement by itself, outside of a function, it works fine -> $.get(scriptURL, {}, function(data) { alert(data); })

I'd like to be able to re-use this code by putting it inside of a function that returns the $.get data. What fundamental mistake am I making here?

Was it helpful?

Solution

You have a few different mistakes. First, $.get doesn't return the return value of the callback function. It returns the XHR object. Second, the get function isn't synchronous, it's asynchronous so showGetResult will likely return before get completes. Third, you can't return something from inside the callback to the outer scope. You can, however, bind a variable in the outer scope and set it in the callback.

To get the functionality that you want, you'll need to use $.ajax and set the async option to false. Then you can define a variable in the outer scope and assign it in the ajax callback, returning this variable from the function.

function showGetResult( name )
{
     var result = null;
     var scriptUrl = "somefile.php?name=" + name;
     $.ajax({
        url: scriptUrl,
        type: 'get',
        dataType: 'html',
        async: false,
        success: function(data) {
            result = data;
        } 
     });
     return result;
}

You would probably be better served, though, figuring out how to do what you want in the callback function itself rather than changing from asynchronous to synchronous calls.

OTHER TIPS

The fundamental mistake you are making is that the AJAX call is made asynchronously, so by the time you return, the result is not yet ready. To make this work you could modify your code like this:

$(function() {
    showGetResult('John');
});

function showGetResult (name) {
    $.get('somefile.php', { 
        // Pass the name parameter in the data hash so that it gets properly
        // url encoded instead of concatenating it to the url.
        name: name 
    }, function(data) { 
        alert(data); 
    });
}

Looks like you want synchronous request: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

Or, you may want to pass callback to your function:

function showGetResult (name, callback) {
  var scriptURL = "somefile.php?name=" + name;
  return $.get(scriptURL, {}, callback);
}

showGetResult("John", function(data){ alert(data); });

The fundamental mistake is the "asynchronous" part of AJAX. Because you don't know how long the server will take to send back a response, AJAX methods never "block" -- that is, you don't call out to the server and just sit there waiting for the result. Instead, you go on to something else, but you set up a method, called the "callback", that will fire when the results come back. This method is responsible for doing whatever needs to be done with the data (e.g. injecting it into the page).

This is the wrong way to do. The function(data) is a call back function so whenever return $.get will execute .. there is possibility that call back function would have not been called.

Better you call your post data get function from function(data) method.

An efficient way is to use jQuery's Deferred method, both sync/async requests to server and wait for deferred.resolve() and then return the deferred promise object. Looks a bit tedious, but a little study is sure helpful for large data. ( tvanfosson's function works well in this case, but when I was working on google analytics data, a large amount of information made me crazy and thus i need to find this solution)

     function showResults(name) { 
        var deferred = $.Deferred, requests = [];

        requests.push($.ajax({url:"/path/to/uri/?name=" + name, type: "GET", async: false}).done(function(d) { 
         //alert or process the results as you wish 
        }));
        $.when.apply(undefined, requests).then(function() { deferred.resolve(); }); 
        return deferred.promise();

    }

the returned promise object can also be used with $.when(showResults('benjamin')).done(function() { }); for post modifications (like chart/graph settings etc). totally reusable. You may also put this function in a loop of $.deferred requests like,

        function updateResults() { 
             var deferred = $.Deferred, requests = [];
             requests.push($.ajax(url:"/path/to/names/?nameArr=" + jsonArrOfNames, type: "GET", async: false}).done(function(res) {  requests.push(showResults(res[0]));}) );
             $.when.apply($, requests).then(function() { deferred.resolve(); }); 
             return deferred.promise();
            }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top