Home > Software engineering >  How to overcome Error: Objects are not valid as a React child (found: [object Promise])
How to overcome Error: Objects are not valid as a React child (found: [object Promise])

Time:08-29

Using async in map( ) function gives me error

Hi I am using Google Map API to get latitude and longitude from address line. Each address line is stored in an object array called data.

I used map( ) function to make custom Markers on google map, but since I need to wait for fetch( ) response for getting the latitude and longitude, I used async keyword inside of map( ): it's written inside of <GoogleMap> tag. But this gives me runntime error, but I don't know how to get runntime error go away while fetching API response. How can I solve this issue?

My code

import React, { useMemo, useState } from 'react'
import { GoogleMap, useLoadScript, InfoWindowF, MarkerF } from "@react-google-maps/api"
import { data } from './data'

const API_KEY = "A1B2C3D4E5F6G" //This is written in .env

export default function GoogleMapAPI() {

  const { isLoaded }: any = useLoadScript({
    googleMapsApiKey: API_KEY,
  })

  const getCoordinates = async (obj: any) => {
    let location = { 'lat': 0, 'lng': 0 }
    await fetch("https://maps.googleapis.com/maps/api/geocode/json?address="   obj.address   '&key='   API_KEY)
      .then(response => response.json())
      .then(data => {
        const latitude = data.results[0].geometry.location.lat;
        const longitude = data.results[0].geometry.location.lng;
        location.lat = latitude
        location.lng = longitude
        console.log(location)
      })
    return (location)
  }

  if (!isLoaded) return <div>Loading...</div>
  return (
    <>
      <GoogleMap
        zoom={11}
        center={{ lat: 35.68545216217928, lng: 139.75273062972732 }}
        mapContainerClassName='my__class'
      >
        <>

          {data.map(async (obj) => {
            let location = await getCoordinates(obj)
            return (
              <>
                <MarkerF 
                  position={{ lat: location.lat, lng: location.lng }}
                  />
              </>
            )
          })
         }
        </>
      </GoogleMap>
    </>
  )
}



CodePudding user response:

You need to fetch all locations upfront:

const [locations, setLocations] = useState([]);

useEffect(() => {
  const fetchLocations = async () => {
    const locations = await Promise.all(data.map(getCoordinates));
    setLocations(locations);
  };
  fetchLocations();
}, []);

And then render them:

{
  locations.map((location) => (
    <MarkerF
      key={`${location.lat} ${location.lng}`}
      position={{ lat: location.lat, lng: location.lng }}
    />
  ));
}

It is also a good idea to move getCoordinates out of component body. So useEffect doesn't depend on it.

  • Related