Question

I have a JSON file set up with data that, when a user on my site selects a music genre from a dropdown menu, songs of that music genre (the songs are stored in the JSON file, along with the artist) will be displayed in a combo box on my site. Sadly, this is not going according to plan.

I know that this error is based around some mistake that I am making, but I don't know where exactly! My browser's console is saying, "Uncaught TypeError: Cannot read property 'undefined' of undefined" on the following statement:

var selectedValue = dropDown.options[dropDown.selectedIndex].value;

However, I don't know what that means or if it's actually a legitimate runtime error. Anyways, here is my code. I would really appreciate it if you awesome people could look over my code and see what you think may be causing my code to not act in the way that I want to it to act (detailed in the first paragraph) :)

JSON

{
    "library":
    [
        // ROCK
        {
            "title": "Your Love",
            "artist": "The Outfield"
        },
        {
            "title": "Voodoo Child",
            "artist": "Jimi Hendrix"
        },
        {
            "title": "When I'm Gone",
            "artist": "Three Doors Down"
        },
        // ALTERNATIVE
        {
            "title": "Jumper",
            "artist": "Third Eye Blind"
        },
        {
            "title": "One Week",
            "artist": "Barenaked Ladies"
        },
        {
            "title": "The Middle",
            "artist": "Jimmy Eat World"
        }
    ]
}

JavaScript

$(document).ready(function()
{
    // Declare our needed variables
    var dropDown = $("#music-genre");    // <select id="music-genre">...</select>
    var selectedValue = dropDown.options[dropDown.selectedIndex].value;
    var target = $('#song');    // <select multiple id="song">...</select>


    // If "Alternative" is chosen, choose the alternative songs
    // I didn't add a conditional statement for choosing "Rock" because it's the same
    if (selectedValue == "Alternative")
    {
        // "data/music.json" is the location of my JSON file
        $.getJSON("data/music.json", function(data)
        {
            $.each(data, function(key, val)
            {
                target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
            }); // END $.each
        }); // END $.getJSON
    } // END if
}); // END ready()

HTML

<!-- Drop Down -->
<select id="music-genre">
    <option id="rock" value="rock">Rock</option>
    <option id="alternative" value="alternative">Alternative</option>
</select>

<!-- Combo Box -->
<select multiple id="song">
    <!-- "Select one or more" is disabled because I don't want users selecting it -->
    <option value="select" disabled>Select one or more</option>
</select>
Was it helpful?

Solution

Your the data you want from your returned JSON is in the library array, so you need to use data.library.

Also note that target will be a jQuery object which does not have a innerHTML property, so you need to use append instead:

$.each(data.library, function(key, val) {
    target.append('<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>');
})

Finally as others mentioned you can use the val() property on a select element to get the selected value:

var selectedValue = $("#music-genre").val();

OTHER TIPS

Try to use it like this:

JSON:

{
"library": {
    "rock": [
        {
            "title": "Your Love",
            "artist": "The Outfield"
        },
        {
            "title": "Voodoo Child",
            "artist": "Jimi Hendrix"
        },
        {
            "title": "When I'm Gone",
            "artist": "Three Doors Down"
        }
    ],
    "alternative": [
        {
            "title": "Jumper",
            "artist": "Third Eye Blind"
        },
        {
            "title": "One Week",
            "artist": "Barenaked Ladies"
        },
        {
            "title": "The Middle",
            "artist": "Jimmy Eat World"
        }
    ]
}

JAVASCRIPT:

$(function(){
    // Declare our needed variables
    var dropDown = $("#music-genre");    // <select id="music-genre">...</select>
    // var selectedValue = dropDown.options[dropDown.selectedIndex].value;
    var target = $('#song');    // <select multiple id="song">...</select>

    dropDown.on("change", function(){
        var genre = $(this).val();
        var html = '';
        $.getJSON("test.json", function(data){
            $.each(data.library[genre], function(key, val){
                html += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';    // Save whole html in a var
            }); // END $.each*/
            target.html(html);  // append it in target div
        }); // END $.getJSON
    });
}); // END ready()

Try to use:

var selectedValue = dropDown.find(':selected').val();

or:

var selectedValue = dropDown.val();

instead of:

var selectedValue = dropDown.options[dropDown.selectedIndex].value;

since dropDown is a jQuery object which required you to use jQuery method here.


Also note that data contains library array, so you need to access this array to get the value inside:

$.each(data.library, function(key, val) {
    target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top