1

It's probably obvious to you, but I can't figure it out.

I need to make function that returns it's inner-function's value. In other words, I have function get_users() that must return JSON object. That JSON object is got by $.post (built-in jQuery).

function get_users() {    
    return
        $.post(
            url_base + 'travel/trip/get_users/' + trip_id,
            function(response) {    
                return response;    
            },
            'json'
        );    
}

(above is what I tried to do, but it returned undefined - what a surprise)

Because of variable scope, I cannot just make variable in inner-function because it won't be visible in main function. I don't want to use global variables neither. Looking for better solution!

Thanks in any advice!

2
  • the post is asynchronous and thus you can not return the values like you're trying to do. If you really need this, though I'd not advice it, set the ajax call to synchronous async: false. Commented Dec 19, 2011 at 8:54
  • 1
    This isn't a simple matter of scoping. AJAX calls are asynchronous. What happens here is 1. You call get_users, which sends off an Ajax Request. get_users is done now. 2. At some point in the very near future, that AJAX request is returned, and the callback function you specified is run (in this case, your callback doesn't do anything particularly interesting). Commented Dec 19, 2011 at 8:56

3 Answers 3

5

Why are you fighting against the asynchronous nature of AJAX? When you do AJAX you should get accustomed to work with events and callbacks instead of writing sequential code. You can't return the inner contents. The simple reason for this is that this inner function could execute much later than the outer function. So the outer function will return a result much before the success callback executes.

So here's the correct way:

function get_users() {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id, 
        function(response) {
            // instead of trying to return anything here
            // simply do something with the response
            // Depending on what the server sent you there
            // will be different ways.

            // Here you could also call some other custom function
            // and pass it the response
        }
        'json'
    );
}
Sign up to request clarification or add additional context in comments.

Comments

3

You can't return values from ajax calls. (Without setting async false, but that wouldn't really be ajax)

By the time you hit the inner return, the outer function has already completed

You will need to use a callback to process the users.

get_users(function(response) { // this anonymous function is passed in as a parameter
    // do something with the response
});

function get_users(callback) {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        function(response) {
            // call the passed in function and pass in the response as a parameter
            callback(response);     
        },
        json'
    );
}

1 Comment

If no additional work is needed, one could use callback directly, without the second anonymous function. :)
2

You need a primer on how asynchronous ajax calls work.

When you call $.post(), it starts a networking call to do the post and immediately returns from the $.post() call and continues executing the rest of your javascript. It will even exit your function get_users() right away.

But, the ajax call is not yet done - it's still in progress. Some time later, the ajax call will finish and when that happens the success handler for the ajax call that you have defined as function(response) {...} will get called. Only then, at that later time, is the response value from the ajax call known.

This is what asynchronous ajax means. You cannot write a call like get_users() and expect it to get the users and return with them. Instead, you have to make use of callback functions that will get called some time later (when the ajax has completed) and you can continue the path of your code then. Yes, this is inconvenient, but it's how things work in javascript with asynchronous ajax calls. The benefit of asynchronous ajax calls is that the browser and other javascript code can be fully live while the ajax call is underway. The cost of asynchronous ajax calls is that coding for them is more complicated.

You have a number of choices for how to deal with this complication. First off, you can make your get_users() call and then just continue the programming sequence that you want to carry out in the internal callback inside of get_users() since that's the only place that the response (the actual users) is known. If you're only using get_users() in one place in your code, then that could work fine. It would look like this:

function get_users() {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        function(response) {

            // process the user list here and continue whatever other code you
            // need that deals with the user list
        },
        'json'
    );
}

If you need to use get_users() in several different places for different purposes, then you can change it to take a callback itself and let the post call just call that callback when the ajax call is done. You would then complete your processing of the response in that callback function:

function get_users(callback) {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        callback,
        'json'
    );
}

In this second option you could call get_users() like this:

get_users(function(response) {
    // process the user list here and continue whatever other code you
    // need that deals with the user list
});

There are even more advanced options available using jQuery's deferred object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.