AJAX Asynchronicity and Functions Within Functions 😖

AJAX Asynchronicity and Functions Within Functions :confounded:
0

#1

Currently working on the twitch tv project and I am having trouble since I am doing two AJAX calls and the data is not going into my variables at the right time it seems.

I have a function initUser() which is supposed to initialize the user by first running another function called getData() which basically gets the user’s offline data and assigns this data to the global object ****userObj. Then another function is run called onlineStatus() which checks if a user is currently streaming by checking if data.stream is null or not. Then finally $().append is used to display the data on the screen.

Problem is I am getting undefined for everything and I know that it has to do with the data from the AJAX request not getting back in time, maybe I’m wrong but it feels to be the case. I have been staring at the code for hours trying to figure this out or trying to refactor it without success.

Would appreciate any help.


#2

I think I struggled with similar problem and I solved it by using .then(). And then from the .then success callback, I could do the next API call. I’m just learning all this stuff and so I’m not sure if this is best solution or if there are other options.

If you like, feel free to check out my project https://codepen.io/barbarap/pen/gGeGMb


#3

The problem is within your initUser function, you have the following:

    var channelsUrl = urlString + "channels/" + user + "?callback=?";
    getData(channelsUrl);
    onlineStatus(user);
    $("#usercontainer").append("<div class='user'><a target='_blank' href='"
        + userObj.url + "'><img src='"
        + userObj.logo + "'></a><span class='username'>"
        + userObj.displayName + "</span><span class='game'>"
        + userObj.game + "</span><span class='status'>"
        + userObj.status + "</span><span class='onlinestatus'>"
        + userObj.onlineStat + "</span></div>");

Since getData and onlineStatus functions contain AJAX calls which are asynchronous, they allow other code to keep running and so the append you attempt references userObj properties which have not been set yet, because the responses have not come back yet from the AJAX calls when they are evaluated in this statement.

How to fix? You are going to have to rethink your logic so that you only append when all the data for a particular user has been received back by both APIs. One suggestion is to modify your existing getData function, so that inside the anonymous success function, you call onlineStatus(user) and then inside the anonymous success function of the AJAX call in onlineStatus function, you put the append. That way, all the data will be ready to append.

NOTE: You still have some issues, but a few well placed console.logs should help you out. Let me know if you have any further questions about anything I have suggested here or if you get stuck again.


#4

Hey, thanks for the reply. I was actually looking into trying to understand .then(). It initially seemed like something that would work for me, I just don’t fully understand it yet. Need to read up on it more. Thanks for the link to your project. I was looking at your code to try and see how you made it work.


#5

I refactored the code in the way that you suggested. Looks like I’m one step closer to my intended result. I am no longer getting undefined for everything. Problem now is that the way the data is being displayed is inconsistent.

Mostly what I am seeing is the same user being displayed over and over. Occasionally there might be 2 or 3 users displayed, but again, they are repeated.

I am looking at the code and it seems to me that either something is not yet right with my onlineStatus() function or that the way that I am handling the userObj is incorrect.


#6

Instead of creating the global userObj, create it locally in the AJAX success function of getData. Then pass this userObj to the onlineStatus function as a 2nd argument. This should help.


#7

Thanks a lot, code is working as intended now!