0

My second select dropdown is populating with each letter of the data I'm returning from my server and not each item itself.

enter image description here

Here's my JQuery;

var selected_table = $("#id_TableName option:selected").text();
            $.get('/historicaldata/input_parameters/', { selected_table : selected_table }, function(data){
                for (var i = 0; i < data.length; i++) {
                    for (var key in data[i]) {
                        $('<option />', {
                            value: key,
                            text: data[i][key]
                        }).appendTo("#id_ColumnName");
                    }
                }
            });

My data looks like this when it is returned from my view after the GET request;

{'option1': ['option1'], 'option2': ['option2'], 'option3': ['option3']}

Although I've tried a few similar formats and the outcome is the same so I think the fault is with the JQuery.

Thanks!

Mark Corrigan
  • 544
  • 2
  • 11
  • 29

2 Answers2

1

Two issues:

  1. It looks to me as though your server isn't returning the correct Content-Type header with the reply, so jQuery doesn't realize it's JSON and auto-deserialize it for you. So your loop loops through the characters of the string.

    You can force the matter by adding a call to jQuery.parseJSON ($.parseJSON if you use the $ shortcut):

    data = jQuery.parseJSON(data);
    

    ...as the first line of the success handler (shown in context below), but the better option would be to correct the Content-Type the server is sending back. The content type the server should be sending back is application/json.

  2. Your code is expecting to get back an array, but from the

    {'option1': ['option1'], 'option2': ['option2'], 'option3': ['option3']}
    

    ...you quoted, you're not sending back an array, you're sending back something like a JSON object (but with invalid quotes, see #3 below). Once you fix #3 below, then you can loop through the names of the properties using for (var propName in data) (propName will be "option1", "option2", etc., in no guaranteed order). If you need a specific order, change your server-side output to output an array instead:

    ["option1", "option2", "option3"]
    

    ...and then stick with your existing loop.

  3. The JSON you're sending back is invalid. JSON requires property names and strings to be in double quotes ("), not single quotes ('). So:

    {"option1": ["option1"], "option2": ["option2"], "option3": ["option3"]}
    

    ...or again, use an array:

    ["option1", "option2", "option3"]
    

Here's the parseJSON call in context, but again, it would be better if the server sent back the correct Content-Type, and you'll also have to update how you access the data:

var selected_table = $("#id_TableName option:selected").text();
$.get('/historicaldata/input_parameters/', {
    selected_table: selected_table
}, function(data) {
    data = $.parseJSON(data);     // <====== Added
    for (var i = 0; i < data.length; i++) {
        for (var key in data[i]) {
            $('<option />', {
                value: key,
                text: data[i][key]
            }).appendTo("#id_ColumnName");
        }
    }
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @MarkCorrigan: Dunno, what server-side technology are you using? Whatever it is, search for "setting content type" or "setting headers" (as `Content-Type` is a standard header). In PHP, for instance, it would be `header("Content-Type: application/json");` In ASP.Net using C#, it would be `Response.SetContentType("application/json");` – T.J. Crowder Jul 28 '14 at 14:05
  • also gettng an error in firefox debugger SyntaxError: JSON.parse: expected property name or '}' are you aware of what this refers to? – Mark Corrigan Jul 28 '14 at 14:08
  • @MarkCorrigan: Probably #3 above. I added that late, when I realized you were using single quotes rather than doubles. (My content type examples in the comment above were also wrong thanks to a typo [been a long day already, it's only 3pm!], hit refresh to make sure you're seeing `application/json` there.) – T.J. Crowder Jul 28 '14 at 14:09
  • `data = $.parseJSON(data); // <====== Added` are you serious? `for (var i = 0; i < data.length; i++) {` and then `parseJSON` ? – webdeveloper Jul 28 '14 at 14:14
  • @webdeveloper: Thanks, I pasted it in the wrong place! Fixed. – T.J. Crowder Jul 28 '14 at 15:01
0

This is your example (you getting string):

Demo: http://jsfiddle.net/5JNSz/

If you fix your string, so it become correct json and use JSON.parse() OR jquery $.parseJSON:

Demo: http://jsfiddle.net/dv9Ly/

Note: object doesn't have length property.

Something like this should work, if you fix content type issue:

for (var key in data) {
    $('<option />', {
        value: key,
        text: data[key][0]
    }).appendTo("#id_ColumnName");
}

Demo: http://jsfiddle.net/Vm7jQ/

webdeveloper
  • 17,174
  • 3
  • 48
  • 47