Search code examples
jqueryajaxbootstrap-4bootstrap-selectpicker

Populate dropdown from JSON


I'm trying to simply populate a dropdown with a JSON response from an API.

let dropdown = $('#LA_picker');

dropdown.empty();

dropdown.append('<option selected="true" disabled>Choose State/Province</option>');
dropdown.prop('selectedIndex', 0);

const url = 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaType%3DnhsTrust%3Bdate%3D2020-12-20&structure=%7B%22name%22:%22areaName%22,%22code%22:%22areaCode%22%7D&format=json&page=1';

$.getJSON(url, function(data) {
  $.each(data.data, function(key, entry) {
    dropdown.append($('<option></option>').val(entry.name).html(entry.name));
    console.log(entry.name);
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="LA_picker" class="selectpicker" data-live-search="true"></select>

When opening the webpage, the dropdown is there with "Choose State/Province", but there are no other options. Note I have put console.log(entry.name); in there to check the console output, which is successful and gives the names of all the entries as expected.

What could I be doing wrong?


Solution

  • From your comment:

    Seems the class "selectpicker" is what breaks it. This is from the Bootstrap-select plugin.

    Since there is a bootstrap selectpicker instance on that <select> element... The instance must be instantiated after the results from the ajax request are received.

    You actually instantiate usint the selectpicker class. Remove it and add dropdown .selectpicker(); in the getJSON callback, AFTER the $.each loop.

    The ajax request takes a bit of time to resolve... And selectpicker is adding some new elements to the DOM, based on the content of the original <select>. That is why the plugin has to be instantiated in the getJSON callback.

    bootstrap-select documentation

    let dropdown = $('#LA_picker');
    
    dropdown.empty();
    
    dropdown.append('<option selected="true" disabled>Choose State/Province</option>');
    dropdown.prop('selectedIndex', 0);
    
    const url = 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaType%3DnhsTrust%3Bdate%3D2020-12-20&structure=%7B%22name%22:%22areaName%22,%22code%22:%22areaCode%22%7D&format=json&page=1';
    
    $.getJSON(url, function(data) {
      $.each(data.data, function(key, entry) {
        dropdown.append($('<option></option>').val(entry.name).html(entry.name));
        console.log(entry.name);
      })
      dropdown.selectpicker();
    });
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/i18n/defaults-*.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>
    
    <select id="LA_picker" data-live-search="true"></select>