rshea0
rshea0

Reputation: 12249

Uncaught TypeError: Cannot set property of undefined

Google Chrome is throwing "Uncaught TypeError: Cannot set property 'isDown' of undefined" but it doesn't look like anything is wrong with my code!

Important part of my variable array:

KEY = {
    UP: 38,
    DOWN: 40,
    W: 87,
    S: 83,
    D: 68
}
pingpong = {
    fps: 60,
    pressedKeys: [],
    complete: false,
}

Key listener initialization (this is where the error is thrown):

    for (var keyCode in KEY) {
        if (KEY.hasOwnProperty(keyCode)) {
            pingpong.pressedKeys[KEY[keyCode]] = {
                isDown: false,
                wasDown: false
            };
        }
    }
    $(document).keydown(function(e) {
        pingpong.pressedKeys[e.which].isDown = true;
    });
    $(document).keyup(function(e) {
/* This line is the issue */    pingpong.pressedKeys[e.which].isDown = false;
    });

Any Ideas?

Upvotes: 0

Views: 23406

Answers (2)

James Allardice
James Allardice

Reputation: 165991

The problem is that you're trying to access an element of the pressedKeys array which does not exist. For example, if we pressed the "a" key:

$(document).keyup(function(e) {
    //Pressed "a" so e.which == 65
    pingpong.pressedKeys[e.which].isDown = false;
});

When you initialize your array you only create elements for the properties of the KEY object:

for (var keyCode in KEY) {
    //Iterating over KEY, which contains 5 properties...
    if (KEY.hasOwnProperty(keyCode)) {
        //Add value to pressedKeys (this happens for each of the 5 properties)
        pingpong.pressedKeys[KEY[keyCode]] = {
            isDown: false,
            wasDown: false
        };
    }
}

So pressedKeys only contains 5 elements, corresponding to the properties of KEY. Note that a TypeError is also thrown in the keydown event handler, as well as keyup.

To fix it, you could check that e.which is in the KEYS object in the event handler functions. If it's not, just ignore it. Something like this perhaps (there may be a better way, this is just what came to mind first):

$(document).keydown(function(e) {
    for(var k in KEY) {
        if(KEY[k] == e.which) {
            break; //Break out of loop and execute last line
        }
        return false; //Key not recognized, last line is not executed
    }
    pingpong.pressedKeys[e.which].isDown = true;
});

Upvotes: 2

user123444555621
user123444555621

Reputation: 153006

e.which is IE only. Real browsers use e.keyCode

jQuery Event Keypress: Which key was pressed?

Upvotes: 1

Related Questions