I have a select element that I populate with data returned from an AJAX call. It workds most of the time but its unreliable. Sometimes it works the first time I click the link and sometimes not (mostly it works). I can see that the server is returning the correct data everytime.

The html here is the state of the home page after the link is clicked but before the data is loaded into the select.

HTML(home.php):

<html>
<body>
<ul id="nav">
    <li><a class="current" href="teachers.php">Home</a></li>
</ul>

 <div class="div_wrap">
   <select size="1" name="teachers" id="s_teachers">
    <option name="o_teacher" value=""></option>
    </select>
 </div>

</body>
</html>

jQuery:

$(document).ready(function() {
    $("body").on("click", "#nav a[href='teachers.php']", function(event){
        loadFormContent(this);
        event.preventDefault();
        var request = $.ajax({  url: "get_data.php",
                                type: "POST",
                                dataType: "json",
                                data: {<my data goes here>},
                                success: function(data, status, jqXHR){
                                        populateSelect(data, status, jqXHR, "teachers")
                                }
                            }); 
        return false;
    });
}

function loadFormContent(target){
    $("#nav li a").removeClass('current');
    $(target).addClass('current');
    $.ajax({ url: target.href, success: function(html) {
        $("#main_content").empty().append(html);
    }});
}

function populateSelect( data, status, jqXHR, name ){
    $(".div_wrap select[name='"+name+"'] option[value!='']").remove();
    var opt_name = $(".div_wrap select[name='"+name+"'] option:first-child").attr("name");
    for( var i=data.length-1; i>=0; i-- ){
        $("<option value='" + data[i]+ "'name='" + opt_name + "'>"+ data[i] + "</option>" ).insertAfter(".div_wrap select[name='"+name+"'] option:first-child");
    }
}

Problem solved. I needed to chain the 2 ajax requests so that the page has fully loaded(first ajax/dom update) before the select options are populated(second ajax/dom update). Populating the options was relying on the page to be loaded and the select element to be present but since the ajax requests were async there was no guarantee of this. So the answer is to chain the requests and make the second request dependent on the success of the first.