1

Is it possible to make a Google Places callback from getDetails function asynchronus or return it's value?

Essentially, in my react app, I am trying to do the following:

  1. pass a placeId to google places api
  2. wait for google to bring back some place information (address, photos, etc)
  3. make a call to my local api to do something with this data from google

What happens though is

  1. google goes to get the data
  2. the call to my api is made but google has not brought back the data yet

I have tried using useState however, the state is not updated right away and thus I am not sure how to "wait" for google places to finish getting data before continuing my call

example of what I am trying to do (obviously wrong)

    const [value, setValue] = useState('')

    const foo = async (placeId) => {
      var service = new window.google.maps.places.PlacesService(
        predictionsRef.current,
      )
      await service.getDetails(
        {
          placeId,
          fields: ['photos'],
        },
        async place =>
          await setValue(
            place.photos[0].getUrl({ maxWidth: 1280, maxHeight: 720 }),
          ),
      )

      // I want 'value' to have google place data before the axios call
      await axios.post(...)
    }

I have looked at the following links so far but can't piece together what I need:

asus
  • 1,427
  • 3
  • 25
  • 59
  • If you `setValue` it won't be available until the *next* render cycle, well after `foo` has finished processing, always. Can you return the value you want from the `service.getDetails` you are awaiting? This or set up a second effect hook to run when `value` updates. – Drew Reese Oct 28 '20 at 05:49

1 Answers1

2

You could make it this way,

const [value, setValue] = useState('')
const [placeID, setPlaceID] = useState(null)

a function to return a promise from google placeDetails API,

const getPlaceDetails = (ref) => {
  return new Promise(function (resolve, reject) {
    let placesService = new window.google.maps.places.PlacesService(ref);
    placesService.getDetails(
      {
        placeId,
        fields: ['photos'],
      },
      (place) => {
        resolve(place.something);
      }
    );
  });
};

an effect that triggers upon placeID change

useEffect(() => {
  async function doStuff() {
    let placesResponse = await getPlaceDetails(ref);
    let myResponse = await yourAPICall(placesResponse);
    setValue(placesResponse);
  }
  if(placeID !==null){
    doStuff();
  }
}, [placeID]);

I haven't tested this code, but hope this approach helps.

Adithya
  • 1,688
  • 1
  • 10
  • 18