Steph
Steph

Reputation: 2185

Javascript Variable Sometimes Undefined

I know this question has been asked several times, but I couldn't seem to find a solution that worked for me in any of the previous questions. I have a variable that gets set when my HTML page is done loading, but sometimes when my code tries to access that variable, it says that it is undefined. I'm not sure why, since I believe I am waiting for everything to load properly. This exception seems to happen randomly, as most of the time all the code runs fine. Here's a simplified version of my code:

var globalVar;

function initStuff(filePath) {
    // I wait till the HTML page is fully loaded before doing anything
    $(document).ready(function(){
        var video = document.getElementById("videoElementID");

        // My parseFile() function seems to run smoothly
        var arrayOfStuff = parseFile(filePath); 

        if (arrayOfStuff == null) {
            console.error("Unable to properly parse the file.");
        } else {
            setGlobalVariable(arrayOfStuff);
            video.addEventListener("play", updateVideoFrame, false);
        }
    });
}

function setGlobalVariable(arrayOfStuff) {
    window.globalVar = arrayOfStuff;
}

function updateVideoFrame() {
    // A bunch of other code happens first

    // This is the line that fails occasionally, saying 
    // "window.globalVar[0].aProperty.anArray[0] is undefined"
    var test = window.globalVar[0].aProperty.anArray[0].aProperty;
}

The only thing that I can think of that might be causing this problem is some sort of synchronicity issue. I don't see why that would be the case, though. Help please!

Edit:

In case the asynchronicity issue is coming from my parseFile(xmlFile) method, here is what I'm doing there. I thought it couldn't possibly be causing the issue, since I force the method to happen synchronously, but in case I'm wrong, here it is:

function parseKML(xmlFile) {
    var arrayOfStuff = new Array();

    // Turn the AJAX asynchronicity off for the following GET command
    $.ajaxSetup( { async : false } );
    // Open the XML file
    $.get(xmlFile, {}, function(xml) {
        var doc = $("Document", xml);   
        // Code for parsing the XML file is here
        // arrayOfStuff() gets populated here
    });

    // Once I'm done processing the XML file, I turn asynchronicity back on, since that is AJAX's default state
    $.ajaxSetup( { async : true } );

    return arrayOfStuff;
}

Upvotes: 1

Views: 1825

Answers (2)

jfriend00
jfriend00

Reputation: 707736

The first thing you should do in your code is figure out which part of:

window.globalVar[0].aProperty.anArray[0]

is undefined.

Since you have multiple chained property references and array references, it could be many different places in the chain. I'd suggest either set a breakpoint right before your reference it examine what's in it or use several console.log() statement sto output each nested piece of the structure in order to find out where your problem is.

console.log("globalVar = " + globalVar);
console.log("globalVar[0] = " + globalVar[0]);
console.log("globalVar[0].aProperty = " + globalVar[0].aProperty);
console.log("globalVar[0].aProperty.anArray = " + globalVar[0].aProperty.anArray);
console.log("globalVar[0].aProperty.anArray[0] = " + globalVar[0].aProperty.anArray[0]);

If the problem is that globalVar isn't yet set, then you have a timing problem or an initialization problem.

If the problem is that one of the other properties isn't set, then you aren't initializing globalVar with what you think you are.

You may also want to write your code more defensibly so it fails gracefully if some of your data isn't set properly.

Upvotes: 2

Larry Battle
Larry Battle

Reputation: 9178

You need to use defensive programming. http://www.javascriptref.com/pdf/ch23_ed2.pdf

Example:

var video = document.getElementById("videoElementID") || 0;

-

if( video && video.addEventListener ){
    video.addEventListener("play", updateVideoFrame, false);
}

Here's another version of your code.

window.globalVar = globalVar || [];
function setGlobalVariable(arrayOfStuff) {
    window.globalVar = arrayOfStuff;
}
function updateVideoFrame() {
    // A bunch of other code happens first

    // This is the line that fails occasionally, saying
    // "window.globalVar[0].aProperty.anArray[0] is undefined"
    if( window.globalVar ){
        var g = window.globalVar || [];
        var d = (g[0] || {})["aProperty"];
        // etc...
    }else{
        console.error( "test error." );
    }

}
function initStuff(filePath) {
    // I wait till the HTML page is fully loaded before doing anything
    $(document).ready(function () {
        var video = $("#videoElementID");

        // My parseFile() function seems to run smoothly
        var arrayOfStuff = parseFile(filePath) || [];

        if (arrayOfStuff == null || video == null ) {
            console.error("Unable to properly parse the file.");
        } else {
            setGlobalVariable(arrayOfStuff);
            video.bind("play", updateVideoFrame);
        }
    });
}

Upvotes: 1

Related Questions