1

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;
}
7
  • is parseFile(filePath) an ajax request? Commented May 17, 2012 at 23:29
  • Seems like your external file has not been totally parsed (occasionally and likely) at the time updateVideoFrame function executes. If it's an Ajax call, you might wanna make it synchronous otherwise you can use a complete function in your Ajax function to call updateVideoFrame. Commented May 17, 2012 at 23:34
  • @Sebas - No, it is a bunch of JQuery calls to parse an XML file. Commented May 17, 2012 at 23:35
  • @inhan - So if I wanted to make it synchronous, should I do that at the beginning of my initStuff() method? I already make a $.ajaxSetup( { async : false } ); call in my parseFile(filePath) function, but at the end of that function I was switching it back using $.ajaxSetup( { async : true } );. Commented May 17, 2012 at 23:38
  • 1
    Also use try catch block to handle the errors... It may help you to find the problem Commented May 18, 2012 at 4:52

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

9 Comments

console.dir() is great for dumping arrays and objects.
Judging by the error message in the comment, everything up to and including anArray is defined, but anArray has no 0 property.
Also use try catch block to handle the errors... It may help you to find the problem
@powerbuoy - Thanks for the console.dir() tip, that was helpful!
@GGG - Yes, but anArray is only undefined sometimes, seemingly randomly, which is why I am confused. When run on the same input, I would think the array should be defined every time, but it's not, which is why I'm having trouble tracking down what is going wrong, and why I think it has to do with synchronization.
|
1

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);
        }
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.