0

I cannot create a global variable in a function

function getFabrics(){
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "af_general.php?action=fabrics", true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            fabrics_json=JSON.parse(this.responseText);
            console.log(fabrics_json);
        }
    };
}

and use it in another:

function addrow(){
    getFabrics();
    var table=document.getElementById('stoixeia');
    var rows = table.getElementsByTagName("tr").length;
    var row = table.insertRow(-1);
    var cell1 = row.insertCell(-1);
    var rowno=rows-1;
    var pcs_ent=document.createElement('input');
    setAttributes(pcs_ent,{'type':'number','id':'pcs.'+rowno,'name':'pcs','style':'width: 4em;text-align:right','min':'0','max':'99','autocomplete':'off'});
    cell1.innerHTML='#'+rowno;
    cell1.appendChild(pcs_ent);
    var cell2 = row.insertCell(-1);
    var fabric_ent=document.createElement('select');
    console.log(fabrics_json);//returns undefined
    for (f in fabrics_json){
        option = document.createElement('option');
        option.value=fabrics_json[f][0];
        option.text=fabrics_json[f][1];
        fabric_ent.add(option);
    }
    //and goes on...
}

I have read all possible questions in stackoverflow but I can't find a way to get the results. fabrics_json remains undefined either if I declare it in the beginning of the script or not.

Filippos
  • 417
  • 1
  • 7
  • 18
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – hindmost Nov 22 '18 at 10:12
  • What if you define fabrics_json globally ? – Mukesh Verma Nov 22 '18 at 10:14

2 Answers2

1

Global variables in JavaScript are members of window object. Refer to your global variable as window.fabrics_json.

If both functions are in the same source file, you can declare var fabrics_json; at global scope and access it both with and without window. prefix.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 3
    Actually the problem have no relation to global variables. It's a typical problem with async calls. – hindmost Nov 22 '18 at 10:18
  • @hindmost I disagree. You can do async in a different way, however, the question is about setting and getting a global variable. – Maxim Egorushkin Nov 22 '18 at 10:18
  • @hindmost This is no where related to async calls. – Mukesh Verma Nov 22 '18 at 10:19
  • @Maxim Egorushkin The quote from OP: _fabrics_json remains undefined either if I declare it in the beginning _of the script or not._ – hindmost Nov 22 '18 at 10:21
  • 1
    The actual problem is that the OP calls `getFabrics` in _sync_ way and expects that AJAX response is available _immediately_ after that call. – hindmost Nov 22 '18 at 10:25
0

I wouldn't use a global variable here... There's no need. You just want a simple callback function.

//Pass in a callback function..
function getFabrics(callback){
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "af_general.php?action=fabrics", true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            callback(JSON.parse(this.responseText));
        }
    };
}


function addrow(){
    // pass in your code to getFabrics as a function to be executed on the callback.
    getFabrics(function(fabrics_json){
        var table=document.getElementById('stoixeia');
        var rows = table.getElementsByTagName("tr").length;
        var row = table.insertRow(-1);
        var cell1 = row.insertCell(-1);
        var rowno=rows-1;
        var pcs_ent=document.createElement('input');
        setAttributes(pcs_ent,{'type':'number','id':'pcs.'+rowno,'name':'pcs','style':'width: 4em;text-align:right','min':'0','max':'99','autocomplete':'off'});
        cell1.innerHTML='#'+rowno;
        cell1.appendChild(pcs_ent);
        var cell2 = row.insertCell(-1);
        var fabric_ent=document.createElement('select');
        console.log(fabrics_json);//returns undefined
        for (f in fabrics_json){
            option = document.createElement('option');
            option.value=fabrics_json[f][0];
            option.text=fabrics_json[f][1];
            fabric_ent.add(option);
        }
        //and goes on...
    });
}
James
  • 4,146
  • 1
  • 20
  • 35