trf
trf

Reputation: 133

Uncaught TypeError: Cannot read property '0' of undefined in select box

I'm not understanding why I am getting the error but the end result is actually what I want. Here is my function:

function populate(){
    for(var i = 0; i < locations.length; i += 1){
        var select = document.getElementById("end");
        select.options[select.options.length] = new Option(buildings[i][0], buildings[i][3]);
    }
};

It pulls in from this array:

buildings = [
            ['Allied Health', '', 'buildings', '35.206815, -101.908493', 2, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building A', '', 'buildings', '35.206718, -101.906127', 3, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building B', '', 'buildings', '35.207614, -101.907383', 4, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building C', '', 'buildings', '35.207545, -101.905702', 5, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building D', '', 'buildings', '35.207408, -101.906485', 6, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Child Development Center', '', 'buildings', '35.207409, -101.908901', 7, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Gymnastics/Dance', '', 'buildings', '35.207264, -101.909682', 8, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Jones Hall', '', 'buildings', '35.207514, -101.908236', 9, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Lecture Hall', '', 'buildings', '35.206754, -101.907246', 10, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['N.W. Library', '', 'buildings', '35.206543, -101.904580', 11, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Delta Building', '', 'buildings', '35.208272, -101.905817', 12, "http://www.actx.edu/staff/images/icons/ac.png"]
];

and populates this onload:

<body onload="populate();">
<select class="form-control" id="end" onchange="calcRoute();">
                    <option disabled selected> -- Select a Destination -- </option>
                </select>

And it actually does what I want it to do, which is put the building name and its coordinates into a select box. But I get this error in my console on chrome:

Uncaught TypeError: Cannot read property '0' of undefined

and it points to this line:

select.options[select.options.length] = new Option(buildings[i][0], buildings[i][3]);

I'm not sure why it throws the error in Chromes console, but still works as intended.

Upvotes: 1

Views: 2305

Answers (1)

Alekos Filini
Alekos Filini

Reputation: 324

Maybe your i variable is just exceeding the buildings lenght. For instance, if you have 20 locations and 15 buildings, when the browser evaluates new Option(buildings[15][0], buildings[15][3]) it throws this error.

EDIT: just to be more specific, supposing we have 15 buildings, our array will have indexs from 0 to 14, thus buildings[15] is undefined. This is where you error comes from, you are trying to read buildings[15][0] that is like reading undefined[0].

You should post the locations variable too in order to get a better response.

var buildings = [

            ['Allied Health', '', 'buildings', '35.206815, -101.908493', 2, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building A', '', 'buildings', '35.206718, -101.906127', 3, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building B', '', 'buildings', '35.207614, -101.907383', 4, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building C', '', 'buildings', '35.207545, -101.905702', 5, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building D', '', 'buildings', '35.207408, -101.906485', 6, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Child Development Center', '', 'buildings', '35.207409, -101.908901', 7, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Gymnastics/Dance', '', 'buildings', '35.207264, -101.909682', 8, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Jones Hall', '', 'buildings', '35.207514, -101.908236', 9, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Lecture Hall', '', 'buildings', '35.206754, -101.907246', 10, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['N.W. Library', '', 'buildings', '35.206543, -101.904580', 11, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Delta Building', '', 'buildings', '35.208272, -101.905817', 12, "http://www.actx.edu/staff/images/icons/ac.png"]          
            ];

var locations = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,];

function populate() {
  for(var i = 0; i < locations.length; i += 1){
    var select = document.getElementById("end");
    select.options[select.options.length] = new Option(buildings[i][0], buildings[i][3]);
    }
};
<body onload="populate();">
<select class="form-control" id="end" onchange="calcRoute();">
                    <option disabled selected> -- Select a Destination -- </option>
                </select>

This code snippet shows what I was talking about (if you open your browser console you should see the same error and this is just caused by the locations array being longer than buildings).

var buildings = [

            ['Allied Health', '', 'buildings', '35.206815, -101.908493', 2, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building A', '', 'buildings', '35.206718, -101.906127', 3, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building B', '', 'buildings', '35.207614, -101.907383', 4, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building C', '', 'buildings', '35.207545, -101.905702', 5, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building D', '', 'buildings', '35.207408, -101.906485', 6, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Child Development Center', '', 'buildings', '35.207409, -101.908901', 7, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Gymnastics/Dance', '', 'buildings', '35.207264, -101.909682', 8, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Jones Hall', '', 'buildings', '35.207514, -101.908236', 9, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Lecture Hall', '', 'buildings', '35.206754, -101.907246', 10, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['N.W. Library', '', 'buildings', '35.206543, -101.904580', 11, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Delta Building', '', 'buildings', '35.208272, -101.905817', 12, "http://www.actx.edu/staff/images/icons/ac.png"]          
            ];

var locations = [0, 0, 0, 0, 0, 0, 0, 0, 0,];

function populate() {
  for(var i = 0; i < locations.length; i += 1){
    var select = document.getElementById("end");
    select.options[select.options.length] = new Option(buildings[i][0], buildings[i][3]);
    }
};
<body onload="populate();">
<select class="form-control" id="end" onchange="calcRoute();">
                    <option disabled selected> -- Select a Destination -- </option>
                </select>

As you can see this second snippet works without giving error (just because i trimmed part of the locations array). I would suggest you to change

for(var i = 0; i < locations.length; i += 1){

with

for(var i = 0; i < buildings.length; i += 1){

in order to show always all of the buildings as you can see in this (finally last) snippet:

var buildings = [

            ['Allied Health', '', 'buildings', '35.206815, -101.908493', 2, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building A', '', 'buildings', '35.206718, -101.906127', 3, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building B', '', 'buildings', '35.207614, -101.907383', 4, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building C', '', 'buildings', '35.207545, -101.905702', 5, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Building D', '', 'buildings', '35.207408, -101.906485', 6, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Child Development Center', '', 'buildings', '35.207409, -101.908901', 7, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Gymnastics/Dance', '', 'buildings', '35.207264, -101.909682', 8, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Jones Hall', '', 'buildings', '35.207514, -101.908236', 9, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Lecture Hall', '', 'buildings', '35.206754, -101.907246', 10, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['N.W. Library', '', 'buildings', '35.206543, -101.904580', 11, "http://www.actx.edu/staff/images/icons/ac.png"],
            ['Delta Building', '', 'buildings', '35.208272, -101.905817', 12, "http://www.actx.edu/staff/images/icons/ac.png"]          
            ];

function populate() {
  for(var i = 0; i < buildings.length; i += 1){
    var select = document.getElementById("end");
    select.options[select.options.length] = new Option(buildings[i][0], buildings[i][3]);
    }
};
<body onload="populate();">
<select class="form-control" id="end" onchange="calcRoute();">
                    <option disabled selected> -- Select a Destination -- </option>
                </select>

Upvotes: 1

Related Questions