I’m retrieving information on Municipality names, ZipCodes, etc. from a public service provider (DAWA) using AJAX. At first I had an issue retriving the data until I made the transfer asyncronous, thus ajaxGetMunicipalitiesFromDAWA
is an asyncronous function. I have checked ajaxGetMunicipalitiesFromDAWA
and it loads data correctly.
The I try to update my selectlist using the data, but it seems the update occurs before Municipalies is loaded. I have tried to make loadMunicipalities
asyncronous as well, but still I end up having an empty option list.
Please help
HTML code:
<div class="row mt-3 fw-bold"> <div class="col-3"><label asp-for="PostalAddress_Municipality">Municipality:</label></div> <div class="col-9"> <select asp-for="PostalAddress_MunicipalityId" class="form-control form-control-sm" name="municipality"></select> </div> </div>
JavaScript:
var Municipalities = ajaxGetMunicipalitiesFromDAWA(); async function ajaxGetMunicipalitiesFromDAWA() { var output = []; var xHttp = new XMLHttpRequest(); xHttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { var dawaData = JSON.parse(this.responseText); dawaData.forEach(function (data) { output.push({ Id: data.kode, Name: data.navn, CountryId: 53, CountryText: "Danmark", RegionId: data.regionskode, RegionText: data.region.navn }); }); } } xHttp.open("GET", "https://dawa.aws.dk/kommuner", true); await xHttp.send(); return output; } async function loadMunicipalities() { var select = document.querySelector("municipality"); var data = await Municipalities; data.forEach(function (municipality) { var option = document.createElement("option"); option.value = municipality.Id; option.text = municipality.Name; option.selected = select.value == municipality.Id; select.add(option); }); }
Advertisement
Answer
Couple of things, XMLHttpResquest.send does not return a promise. So awaiting send
will just await for the an empty microtask to complete and not actually the request. What you’d want to do is just wrap the request in a Promise
which will be handled by the async FSM. You also need to actually call loadMunicipalities
so that the list is actually populated. Below is a working example.
var Municipalities = ajaxGetMunicipalitiesFromDAWA(); async function ajaxGetMunicipalitiesFromDAWA() { var output = []; var xHttp = new XMLHttpRequest(); return new Promise((resolve) => { xHttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var dawaData = JSON.parse(this.responseText); dawaData.forEach(function(data) { output.push({ Id: data.kode, Name: data.navn, CountryId: 53, CountryText: "Danmark", RegionId: data.regionskode, RegionText: data.region.navn }); }); resolve(output); } } xHttp.open("GET", "https://dawa.aws.dk/kommuner", true); xHttp.send(); }); } async function loadMunicipalities() { var select = document.querySelector("#municipality"); var data = await Municipalities; data.forEach(function(municipality) { var option = document.createElement("option"); option.value = municipality.Id; option.text = municipality.Name; option.selected = select.value == municipality.Id; select.add(option); }); } loadMunicipalities();
<select id="municipality"></select>
So this works as is, but since you are using semi modern apis, id recommend that you use fetch as it handles almost all the fixes applied but makes the code much less verbose.
const requestMunicipalitiesFromDAWA = async() => { const response = await fetch("https://dawa.aws.dk/kommuner"); const data = await response.json(); return data.map((datum) => ({ Id: datum.kode, Name: datum.navn, CountryId: 53, CountryText: "Danmark", RegionId: datum.regionskode, RegionText: datum.region.navn })); }; const populateMunicipalitiesOptions = (data) => { var select = document.querySelector("#municipality"); data.forEach(function(municipality) { var option = document.createElement("option"); option.value = municipality.Id; option.text = municipality.Name; option.selected = select.value == municipality.Id; select.add(option); }); }; requestMunicipalitiesFromDAWA().then(populateMunicipalitiesOptions);
<select id="municipality"></select>