0

Good day. I am trying to work with JavaScript global variables when getting data from an external API however when I edit the data of the devList variable in the req2.onreadystatechange() the changes aren't permanent as in the last line where I try to add it to the table devList is empty. Please advise on why the variable changes aren't permanent. Also when I populate the table within the req2.onreadystatechange() the table is populated in some random order every time I refresh the page but then the devList is used correctly. I have also tried using window.devList everywhere but with the same failed result.

const req1=new XMLHttpRequest();
const rawgAPIkey="*******************"; //real key is used here
const baseurl="https://api.rawg.io/api";
const url=new URL(baseurl+"/games");
var tbl=document.getElementById("gametable");
url.searchParams.set("key", rawgAPIkey);
var devList = "";
req1.open("GET", url);
req1.responseType="text";
req1.send();
req1.onreadystatechange=function(){
    if(req1.readyState===4 && req1.status===200){
        var gameArr = JSON.parse(req1.responseText).results;
        for (let index = 0; index < gameArr.length; index++) {
            var game;
            var url2=new URL(baseurl+"/games/"+gameArr[index].id);
            url2.searchParams.set("key", rawgAPIkey);
            const element = gameArr[index];
            const req2=new XMLHttpRequest();
            req2.open("GET", url2);
            req2.responseType="text";
            req2.send();
            var developer="";
            req2.onreadystatechange=function(){
                devList = "";
                if(req2.readyState===4 && req2.status===200){
                    var gamedevs=JSON.parse(req2.responseText).developers;
                    for (let i = 0; i < gamedevs.length; i++) {
                        devList += gamedevs[i].name + ", "; 
                    }
                    console.log(devList);
            }
            }
            tbl.innerHTML+=
            "<tr>"
            +" <td> " + " <p> " + gameArr[index].name +  " </p> "
            + "<img class=\"gamepic\" src=\" "+ gameArr[index].background_image + " \"               alt=\"CS:GO\">" + " </td> "
            + "<td>" + devList + "</td>";
            
        }
    } 
}

EDIT: I have now done the following with promises but it still does not populate the developer column. Please advise if I used promises wrong.

async function getDev(){
                let myProm= new Promise (function(success, fail){
                    const req2= new XMLHttpRequest();
                    req2.open("GET", url2);
                    req2.responseType="text";
                    
                    req2.onload=function(){
                        if(req2.status===200){
                            var gamedevs=JSON.parse(req2.responseText).developers;
                            devList="";
                            for (let i = 0; i < gamedevs.length; i++) {
                                devList += gamedevs[i].name + " ";
                            }
                            success(devList);
                        }else{
                            fail("Developer unavailable");
                        } 
                    };
                    req2.send(); 
                });
                document.getElementById(curDev).innerHTML= await getDev();
            }
            getDev();

1 Answers1

0

since req2.onreadystatechange is asynchronous, there's no guarantee that devList will be assigned before the table is populated.

you can make use of Promise feature or you can also try moving "tbl.innerHTML+.." inside the callback

M.Samir
  • 1
  • 1