0

I had a headache debugging the following code :

Presentation

If I run the following code :

$.get('/api/Customer/1', function(data){
    projects = data.data.projects;
    var $el = $('#mySelect');
    $el.empty();
    projects.forEach(function(element, index, array){
        var text = element.name;
        addSelectOption("mySelect", element.idProject, text);
    });
});

/**
 * Function which add an option to the select input which id is idSelect.
 */
function addSelectOption(idSelect, value, text)
{
    var option =
            $('<option></option>').attr("value", value).text(text);
    $('#' + idSelect).append(option);
}

My select will look like :

<select id="mySelect">
    <option value="1">proj1</option>
    <option value="2">proj2</option>
    <option value="3">proj3</option>
    <option value="4">proj4</option>
</select>

Failure

So, if I append the following line after my ajax code :

$('#mySelect').val("2");

My select should display proj2. But it doesn't.

Success

The only way I found to make it work is the following code :

$.get('/api/Customer/1', function(data){
    projects = data.data.projects;
    var $el = $('#mySelect');
    $el.empty();
    projects.forEach(function(element, index, array){
        var text = element.name;
        addSelectOption("mySelect", element.idProject, text);
    });
    $('#mySelect').val("2");//the only change between the presentation code
});

It looks like the html generated by jquery has a scope which is the get ajax request.

Question

I don't understand why the first code fail to set the selected value of mySelect to proj2. Can you explain it to me please ?

Moebius
  • 6,242
  • 7
  • 42
  • 54

2 Answers2

2

It's because ajax request is asynchronous. The option with value 2 is not created when you ask val() function to set it. When you put it into ajax callback option is available and it set correctly.

SSA
  • 5,433
  • 4
  • 36
  • 50
2

In addition to what @SSA said, here is how you can solve it using a callback:

$.get('/api/Customer/1', function(data){
    projects = data.data.projects;
    var $el = $('#mySelect');
    $el.empty();
    projects.forEach(function(element, index, array){
        var text = element.name;
        addSelectOption("mySelect", element.idProject, text);
    });
}).done(function(){ // <- Called when the $.get is completed
    $('#mySelect').val("2");
});

Or you can just do the operation inside the $.get success callback along with your other code.

Johan
  • 35,120
  • 54
  • 178
  • 293