1

I have a bunch of code that I think is supposed to populate a "category" select box from the value in another "subject" select box.

views.py

def get_categories(request, subject_id):
    subject = Subject.objects.get(pk=subject_id)
    categories = subject.category_set.all()
    category_dict = {}
    for cat in categories:
        category_dict[cat.id] = cat.name
    return HttpResponse(json.dumps(category_dict), content_type="application/json")

urls.py

url(r'^get_categories/(?P<subject_id>\d+)/$', views.get_categories, name='get_categories'),

jquery

$(document).ready(function(){
    $('select[name=subject]').change(function(){
        subject_id = $(this).val();
        request_url = '/get_categories/' + subject_id + '/';
        $.ajax({
            url: request_url,
            success: function(data){
                $.each(data[0], function(key, value){
                    $('select[name=category]').append('<option value="' + this.key + '">' + this.value +'</option>');
                });
            }
        })
    })
});

the request is passing the json data as far as I can tell, Javascript is giving an error:

Uncaught TypeError: Cannot read property 'length' of undefined

I tired changing data[0] to data and that removed the error but all the fields showed up as undefined in the select box.

1 Answer 1

2

If your JSON is valid, you should use data (not data[0]) and your problem is most likely here:

$('select[name=category]').append('<option value="' + this.key + '">' + this.value +'</option>');

The this keyword in $.each returns the value, but as an object. See: http://api.jquery.com/jquery.each/

The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value.

So this.key and this.value will give you undefined.

This should work (again, assuming your JSON is valid):

success: function(data){
    $.each(data, function(key, value){
        $('select[name=category]').append('<option value="' + key + '">' + value +'</option>');
    });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Note also that it's really inefficient to query the select each time. Do it once, before the each loop, store it in a local variable and reference it from there inside the loop.

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.