0

I know there's a bunch of questions on here with similar issues to mine, but after trying several suggestions from all of them, I'm still running into issues that I believe are being caused by the asynchronous behavior of my AJAX calls.

The basic flow is this:

Click button -> getInfo(makeList)
                AJAX call... success: makeList();
                    -> makeList()
                       var friendArray = getFriends(createArray);
                    -> getFriends(createArray)
                       AJAX call... success: return createArray(data);
                           -> createArray(data)
                              var friends = new Array();
                              var friendID = data.id;
                              var friendName = getName(friendID);
                              friends.push(friendName + ":" + friendID);
                              return friends;
                                  -> getName(id)
                                     AJAX call... success: return data.name;

Here's the gist of the code:

$("#submit").click(getInfo(makeList));

function getInfo(callback) {
    $.ajax({
        ...
        success: function(data) {
            ...
            callback();
        }
    });
}

function makeList() {
    var friendArray = getFriends(createArray);
    for (var n in friendArray) {
        $("#friends").append("<option value=\""
            + friendArray[n].split(":")[1] + "\">"
            + friendArray[n].split(":")[0] + "</option>");
        }
}

function getFriends(callback) {
    $.ajax({
        ...
        success: function(data) {
            ...
            return callback(data);
        }
    });
}

function createArray(data) {
    var friends = new Array();
    for (var i in data) {
        var id = data[i].id;
        var friendName = getName(id);
        friends.push(friendName + ":" + id);
    }
    return friends;
}

function getName(id) {
    $.ajax({
        ...
        success: function(data) {
            ...
            return data.name;
        }
    });
}

I have a console.log(friendArray) call at the beginning of makeList(), immediately following the call to var friendArray = getFriends(createArray) and it prints out friendArray = undefined so what I assume is happening is that the function is just continuing without waiting for the getFriends(createArray) function to complete.

It also seems as though the createArray(data) function is not waiting for the getName(data.id) function to complete, and so all the names are coming back as undefined.

As you can see, I've tried passing in the various functions as callback functions, but it didn't do me any good. Any pointers to what I'm doing wrong or what I should change to get the desired behavior would be greatly appreciated!

Mark
  • 829
  • 11
  • 22
  • 1
    possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Barmar Mar 18 '14 at 08:13
  • How can we tell what you're doing wrong when you haven't posted a single line of code? But the fact that you have `return` in your tree indicates that you don't understand the nature of _asynchronous_ operations. – Barmar Mar 18 '14 at 08:14
  • I saw that post and I tried following the **2. Restructure code** solution, but I couldn't get it to work :/ Not sure what I did wrong – Mark Mar 18 '14 at 08:14
  • @Barmar I thought my code would be too confusing, but I'll add it if it helps, will take a minute to edit – Mark Mar 18 '14 at 08:15

1 Answers1

1

Change your makeList function:

function makeList() {
  getFriends(function(data){
    var friendArray = createArray(data);
    for (var n in friendArray) {
        $("#friends").append("<option value=\""
            + friendArray[n].split(":")[1] + "\">"
            + friendArray[n].split(":")[0] + "</option>");
        }
  });
}

Calling getFriends(createArray) will return undefined as the ajax call inside the function is asynchronous. Once the ajax call to be initiated is called. The function returns to its caller and ajax continues independently. Since you need to make sure you have the loop over friendArray executes only after the ajax returns, that should be executed on callback too.

Ahmed Abbas
  • 952
  • 11
  • 25
  • Your answer makes sense, but I forgot to mention that the getFriends() function takes two string parameters as well. Is there any way for me to still pass in those string parameters along with the anonymous function? – Mark Mar 19 '14 at 09:12
  • You can change your function accordingly. If you still need help, paste the skeleton of the function may be. – Ahmed Abbas Mar 19 '14 at 12:00
  • Thanks for your help @ahmed. I think I have all the AJAX callbacks working properly now, but I'm encountering a new issue that I believe is related to having an AJAX function inside a for loop. Is it improper to call a function that contains an AJAX call within it inside a for loop? – Mark Mar 22 '14 at 11:07
  • This jsfiddle isn't working yet, but this is the general code I'm running into issues with: [jsfiddle](http://jsfiddle.net/2prKy/) – Mark Mar 22 '14 at 11:08