-2

I'm looking to run a callback function before the function ends. However, the callback seems to be asynchronous, and the array I'm building ends up as undefined. Here is the code below:

  function getLocDetails(location) {
    const google = window.google
    const service = new google.maps.places.PlacesService(mapRef.current)

    var request = {
      placeId: location.place_id
    }

    function callback(place, status) {
      if (status === google.maps.places.PlacesServiceStatus.OK) {
        // console.log(place)
        return place
      }
    }

    let tempDetailedPlace = service.getDetails(request, callback)
    console.log(tempDetailedPlace)
    return tempDetailedPlace
  }

tempDetailedPlace always returns as undefined. I have checked to make sure the google-maps-api is correct, and I have used that same function elsewhere (it's working correctly). Is there any way to make the callback synchronous or make it pause right before the return statement? Or do I need to implement some kind of async function? Thanks!

2 Answers2

0

service.getDetails must be returning a promise, so you either need to add a .then() block after the call something like,

service.getDetails(request).then(callback)

assuming you want to your callback function to be called after getting the response.

or make this function async and add await before the call to wait for the async task to finish.

Madhur Bansal
  • 176
  • 1
  • 6
0

In this case, the return statement in the callback function is swallowed and does not do anything for you. Since, as you recognize there is some asynchronous activities involved here this code must be treated differently.

The modern approach is to use Async/Await

The following code demonstrates this approach.

A few notes:

  1. Note the use of async and await
  2. The callback() method no longer has a return, but sets a property value
  3. The call to service.getDetails() is asynchronous - this is the solution you seek
  4. This now returns the result of the async value

Finally, the last line shows you how to call getLocDetails().

The return from that function is a Promise object that you use .then() with to process the async results returned.

async function getLocDetails(location) {
  const google = window.google
  const service = new google.maps.places.PlacesService(mapRef.current)
  let processedOutput;

  var request = {
    placeId: location.place_id
  }

  function callback(place, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      // console.log(place)
      processedOutput = 'something you want this to be';
    }
  }

  await service.getDetails(request, callback);
  return processedOutput;
}

getLocDetails(someLocation).then(output => { console.log(output); });
Randy Casburn
  • 11,404
  • 1
  • 12
  • 26
  • Thank you so much for replying. I have tried this version of async/await but the output still seems to be undefined. I'm calling the asynchronous `getLocDetails` in a synchronous function called `getPlacesDetailes`. Would that affect the async lifecycle? – Aryan Indarapu Dec 30 '20 at 12:14
  • No, that will not have an adverse effect. But, please ensure you are only using the output from `getLocDetails()` within the `.then(/* output can only be used here */ )`. You cannot assign the output to a variable outside the then - that will produce `undefined`. – Randy Casburn Dec 30 '20 at 14:06