1

I've tried lots of solutions including How should I call 3 functions in order to execute them one after the other? and Proper Way to Make API Fetch 'POST' with Async/Await but none worked for me.

In my application, I want to fetch data from various APIs into HTML inputs. First I fetch regions, categories, and sectors. Because these 3 fields are select inputs, I set their select options with the returned data. Then I fetch organization details to fill the other text input fields. Problem is that, code that sets the values for the inputs do not wait for all data fetching to be complete so it sometimes returns undefined

My code is

async function loadData() {

  var organisation_id = document.getElementById("organisation_id").innerText;

  console.log("Fetching sectors")
  // Fetch sectors
  let fetchSectors = await fetch("/get-organisation-sectors");
  let sectorsData = await fetchSectors.json();

  var sectors = sectorsData;
  var $sectorselect = $("#sector");
  $sectorselect.html('<option value=""> Choose... </option>');
  $.each(sectors, function (key, val) {
    $sectorselect.append(
      '<option value="' + val.sector_name + '">' + val.sector_name + "</option>"
    );
  });
  // Done fetching sectors

  console.log("Fetching categories")
  // Fetch categories
  let fetchCategories = await fetch("/get-organisation-categories");
  let categoriesData = await fetchCategories.json();

  var categories = categoriesData;
  var $categoryselect = $("#category");
  $categoryselect.html('<option value=""> Choose... </option>');
  $.each(categories, function (key, val) {
    $categoryselect.append(
      '<option value="' + val.category_name +'">' + val.category_name + "</option>"
    );
  });
  // Done fetching categories


  console.log("Fetching regions")
  // Fetch regions
  let fetchRegions = await fetch("http://apis.bigdataghana.com/get_regions");
  let regionsData = await fetchRegions.json();

  var regions = regionsData;
  var $regionselect = $("#region");
  $regionselect.html('<option value=""> Choose... </option>');
  $.each(regions, function (key, val) {
    $regionselect.append(
      '<option value="' + val.region + '">' + val.region + "</option>"
    );
  });
  // Done fetching regions

  console.log("Fetching organisation details")
  // Fetch organisation details
  let fetchOrganisationData = await fetch("/get-organisation-details/" + organisation_id);
  let organisationDetailsData = await fetchOrganisationData.json();

  organisationData = organisationDetailsData[0];

  return await organisationData;
}
loadData().then((data) => {
  setValues(data);
}).catch(e => console.log(e));

The function that sets the values is

function setValues(organisationData) {
  $("#organisation_name").val(organisationData.name);
  $("#email").val(organisationData.email);
  $("#phone").val(organisationData.phone);
  $("#website").val(organisationData.website);
  $("#locality").val(organisationData.locality);
  $("#address").val(organisationData.address);
  $("#latitude").val(organisationData.latitude);
  $("#longitude").val(organisationData.longitude);
  $(function () {
    $("#category").val(organisationData.category);
  });
  $(function () {
    $("#sector").val(organisationData.sector);
  });
  $(function () {
    $("#region").val(organisationData.region);
  });
  var $districtselect = $("#district");
  $districtselect.html('<option value=""> Choose... </option>');
  $districtselect.append(
    '<option value="' +
    organisationData.district +
    '">' +
    organisationData.district +
    "</option>"
  );

  $(function () {
    $("#district").val(organisationData.district);
  });

}
halfer
  • 19,824
  • 17
  • 99
  • 186
  • you may use Promise.all to wait that all data is fetched https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all. However, you will have to rewrite your code to use Promises – Pierre Apr 11 '20 at 15:38
  • 1
    You are using await properly at least as far as the fetch calls go, so I don't see any way things can be unpredictable in the way you described. Either the responses themselves are not always what you expect (have you checked the network panel? Have you used console.log after each fetch?) or it is something else. The "return await" at the end does not do anything useful btw, and organisationData is an undeclared variable but that is probably not your main issue. – Tom Boutell Apr 11 '20 at 15:58
  • 1
    "*code that sets the values for the inputs*" - which code do you refer to? – Bergi Apr 11 '20 at 16:07
  • @Bergi There is a function that I use to set the values. It takes organisation details as a parameter – Rich Dodzi Atitsusi Apr 11 '20 at 16:13
  • @TomBoutell After each fetch, the data logs to console as expected. The whole thing works fine on my localhost but returns undefined when I upload it to the server. When I refresh the page twice, then the values are set which is weird – Rich Dodzi Atitsusi Apr 11 '20 at 16:16
  • @RichDodziAtitsusi Where's the code for that function? Where is it called? What exactly is the error? – Bergi Apr 11 '20 at 18:30
  • @Bergi I have edited the question to include the setValues function. It is called after the data is loaded – Rich Dodzi Atitsusi Apr 11 '20 at 18:41
  • @RichDodziAtitsusi Ok, as Tom already said the `await`s are placed properly so that it should definitely wait for the ajax calls. What exactly happens when the problem occurs? – Bergi Apr 11 '20 at 19:07
  • @RichDodziAtitsusi Notice your usage of `$(function() { … })` is a bit weird. There should be only one such block, not multiple ones. And you will also need to wait for domready with the dom manipulations in `loadData` - or wait with the entire `loadData()` call. – Bergi Apr 11 '20 at 19:09
  • Sorry for the late reply @Bergi I got rid of the ridiculous $(function() {..}) usage multiple times. And I also placed the function call in a `document.addEventListener('DOMContentLoaded', function(event) { loadData() })` This works perfectly on my localhost but when I upload it to the server, it behaves in a weird manner. When the page is loaded at first, it shows undefined for the organisationDetails (it doesn't work) but when the page is refreshed, it works fine – Rich Dodzi Atitsusi Apr 13 '20 at 14:00

0 Answers0