Ronan Byrne
Ronan Byrne

Reputation: 257

How to wait for fetch to complete before running another function

I am currently trying to create a map with markers on it and I would like some of the markers to be represented by a different icon if a user has previously indicated that this marker is one of their "favourites".

To do this I am trying to use a function that fetches first and then pushes part of the data into an array and I am then using another function to create a map and populate it with markers. I would like this second function run only after the first function has complete. Unfortunately every time I run the code all the markers are the same and it seems that the array which should contain the ID of all the favourite stops is empty. I think this means that the await is not working correctly as the first function has not finished running.

The code is:

var favouriteStops = []

async function firstFunction(){
    fetch("api/favstop/")
    .then(response => {
        return response.json();
    })
    .then(data => {
    for(var i = 0; i<= data.length; i++){
        favouriteStops.push(data[i].stopid)
     }
 })
};


function addFavStop (){
        console.log(favouriteStops)
    }

async function initMap(){

    await firstFunction();
    //Map options
    var options = {
        zoom: 15,
        center: {lat:53.3477, lng:-6.2800},
        styles: mapStyle,
        disableDefaultUI: true
    }

    //Creating the map 
    var map = new google.maps.Map(document.getElementById('map'), options);


    //Add marker function
    function addMarker(stop){

        var coords = {lat: stop.lat, lng: stop.long}
        //Style for the icon
        if (favouriteStops.includes(stop.id)){
            var icon = {
                url: '../static/images/favourite.png',
                scaledSize: new google.maps.Size(12, 12)
            };
        } else {
            var icon = {
                url: '../static/images/bus-stop.png',
                scaledSize: new google.maps.Size(12, 12)
            };
            console.log(favouriteStops, stop.id)
        }

        var marker = new google.maps.Marker({
            position: coords,
            map:map,
            icon: icon,
            scaledSize: new google.maps.Size(1, 1),
            name:stop.name,
            id:stop.id
        })

        var infoWindow = new google.maps.InfoWindow({
            content: marker.name + '<br>' + '<button htmlType="submit" onClick=addFavStop()> Add Stop As Favourite </button>'
        });

        marker.addListener('click', function(){
            infoWindow.open(map, marker);
        });

    }

    //Adding markers for each stop
    for(var i = 0;i < stops_import.length;i++){
        addMarker(stops_import[i]);
    }
}

Upvotes: 1

Views: 15104

Answers (3)

silencedogood
silencedogood

Reputation: 3299

You don't need to use the promise chain within an async function. In fact, it kinda defeats the whole purpose. So, your async function would look kinda like this:

async function firstFunction(){
   const fetcher = await fetch("api/favstop/");
   const data = await fetcher.json();
   
   for(var i = 0; i<= data.length; i++){
      favouriteStops.push(data[i].stopid)
   }
};

Upvotes: 1

palaѕн
palaѕн

Reputation: 73886

You can easily resolve this issue by using await inside firstFunction like:

async function firstFunction() {
  const response = await fetch("api/favstop/")
  const data = await response.json();
  for (var i = 0; i <= data.length; i++) {
    favouriteStops.push(data[i].stopid)
  }
};

Or, just return the promise like:

async function firstFunction() {
  return fetch("api/favstop/")
    .then(response => {
      return response.json();
    })
    .then(data => {
      for (var i = 0; i <= data.length; i++) {
        favouriteStops.push(data[i].stopid)
      }
    })
};

Upvotes: 1

geekonaut
geekonaut

Reputation: 5954

For await to actually wait until fetch is done, you should return the promise:

async function firstFunction(){
  return fetch("api/favstop/")
  .then(response => {
    return response.json();
  })
  .then(data => {
    for(var i = 0; i<= data.length; i++){
      favouriteStops.push(data[i].stopid)
    }
  })
};

Upvotes: 2

Related Questions