0

Have been trying to set a global var in javascript to be access from another function,
but there is a particular global var that I can't access, it returns null.
It works if i declare the var in the function itself.

Note: I am unable to use any js library.

This does not works:

var xhttp = new XMLHttpRequest(); <-- this works as the request in the function runs.
var DialogBody = document.getElementById("DialogBody");//<-- this is the problem

function fetchDialog() {
    url = "../message/user_status.php";
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            console.log("OK");// returns ok.
            /*below all return error*/
            DialogBody.innerHTML = "TEST";//<-- error: Cannot set property 'innerHTML' of null
        }
    }   
}

This works:

function fetchDialog() {
    url = "../message/user_status.php";
    var DialogBody = document.getElementById("DialogBody");     
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            console.log("OK");// returns ok.            
            DialogBody.innerHTML = "TEST";//This works.
        }
    }   
}   

So my question is, how do I set that var as global instead of in function.

EDIT:(Solves by links provided by SO user.) <- not what I want.

var xhttp = new XMLHttpRequest();
var DialogBody;
document.addEventListener("DOMContentLoaded", function(event) {
DialogBody = document.getElementById("DialogBody ");
});

function fetchDialog() {
    url = "../message/user_status.php";
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            //console.log("OK");
            DialogBody.innerHTML = "TEST";
        }
    }   
}

UPDATE:(What I actually wanted.)

A little not so pretty workaround is this though it might be frown upon. What I was actually trying to achieve is to set global var (consolidated).
I end up using eval() to set those var as string to achieve what I want and I find myself it very useful.

javascript concept

/.....
var xhttp = new XMLHttpRequest();
DialogBody = 'document.getElementById("DialogBody")';
//or DialogBody = 'document.getElementById("DialogBody").innerHTML';

function fetchDialog() {
    url = "../message/user_status.php";
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            //console.log("OK");
            eval(DialogBody).innerHTML="Test";
            //or eval(DialogBody) = "a message that is dynamically generated";
            //eval(DialogBody).className="Whatever";
        }
    }   
}

actual scenario.

user_status.php

//..query ends.
<div id="DialogTitleMessage">
    <?php echo $DialogTitle;?>
</div>
<div id="DialogBodyMessage">
    <?php echo $DialogTitle;?>
</div>

actual javascript

//.....
var xhttp = new XMLHttpRequest();
DialogBody = 'document.getElementById("DialogBody")';
DialogTitle = 'document.getElementById("DialogTitle")';
DialogTitleMessage = 'document.getElementById("DialogTitleMessage")';

function fetchDialog() {
    url = "../message/user_status.php";
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            eval(DialogBody).innerHTML = xhttp.responseText;
            eval(DialogTitle).innerHTML = eval(DialogTitleMessage).innerHTML;
        }
    }   
}
Mark Ng
  • 200
  • 3
  • 11
  • 1
    Are you sure your element exists when you are doing your `document.getElementById` outside of the function ? – Gwendal Feb 11 '16 at 12:37
  • @Gwendal Almost certainly not, which is addressed in detail in the duplicate I linked. – James Thorpe Feb 11 '16 at 12:38
  • Instead of declaring a global variable, you should define `DialogBody` on `window.onload`. There is a possibility that your script runs before DOM is rendered. – Rajesh Feb 11 '16 at 12:40
  • are you sure your scripts are at the bottom of the page?? – varun teja Feb 11 '16 at 12:40
  • A very simple solution will be to place your script right before closing `body` tag. `getElementById` `returns` `null` because when it is trying to access the element, it is not there in the `DOM` – Rayon Feb 11 '16 at 12:45
  • Edited with a workaround instead of using DOM ready. – Mark Ng Feb 13 '16 at 17:35

4 Answers4

0

You need to execute getElementById when DOM is loaded, try this:

window.onload = function() {
    window.DialogBody = document.getElementById("DialogBody");
};
jcubic
  • 51,975
  • 42
  • 183
  • 323
  • I believe, SO is trying to access element before it is rendered. Using `window.onload` will solve issue and there is no need for global variable. – Rajesh Feb 11 '16 at 12:41
0
var DialogBody; //Declaring

window.onload = function() {
    DialogBody = document.getElementById("DialogBody"); //Intializing
};    

function fetchDialog() {
        url = "../message/user_status.php";
        xhttp.open('POST',url,true);
        xhttp.send();
        xhttp.onreadystatechange = function() {
            if(xhttp.readyState == 4 && http.status == 200) {
                showOverlay();
                DialogBody.innerHTML = "TEST"; //Use here
            }
        }   
    }
Abbas Galiyakotwala
  • 2,821
  • 2
  • 15
  • 34
0

Try putting your var inside a document.addEventListener function :

document.addEventListener("DOMContentLoaded", function(event) { 
    var DialogBody = document.getElementById("DialogBody");
    fetchDialog();
});

or

var DialogBody;
document.addEventListener("DOMContentLoaded", function(event) { 
     DialogBody = document.getElementById("DialogBody")
    fetchDialog();
});

Instead of

window.onload = function() {
    DialogBody = document.getElementById("DialogBody"); //Intializing
};

So the var will be declared after the document has been loaded.

The difference between window.onload and document.addEventListener is that you can use several time document.addEventListener when you can use only once window.onload.

Also just to let you know window.onload will be active after the window is loaded (image, videos...), and document.addEventListener will be active after the documentis loaded.

Hugz
  • 123
  • 6
0

try this:

window.onload = function() {
window.DialogBody = document.getElementById("DialogBody");
};

OR THIS:

    var DialogBody;// by declaring this variable globally you can access it anywhere and also can avoid scope conflicts

    function fetchDialog() {
    url = "../message/user_status.php";
    DialogBody = document.getElementById("DialogBody");     
    xhttp.open('POST',url,true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if(xhttp.readyState == 4 && http.status == 200) {
            showOverlay();
            console.log("OK");// returns ok.            
            DialogBody.innerHTML = "TEST";//This works.
        }
    }   
}   
varun teja
  • 244
  • 3
  • 10