Search code examples
reactjsopenstreetmaplatitude-longitudegeocodereact-leaflet

Invalid latlng object - React Leaflet


  const [geoData, setGeoData] = useState([]);

  useEffect(() => {
    (async () => {
      const forGeoCode = await axios(
        "https://api.opencagedata.com/geocode/v1/json?q=United%20States&key={accessToken}&language=en&pretty=1"
      );
      setGeoData(forGeoCode.data.results[0].geometry);
    })();
  }, []);
  console.log(geoData.geometry);
  return (
    <div>
      <Map center={[52.6376, -1.135171]} zoom={12}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        />
        <Marker position={[geoData.lat, geoData.lng]} />
      </Map>

The above code gives me the following error: Error: Invalid LatLng object: (undefined, undefined)

console.log prints in longitude and latitude but i'm still getting error.

Expected behavior: Take United States as input and return its longitudes and latitudes and plot it on map


Solution

  • You initialize geoData like array empty []

    You should initialize:

    const [geoData, setGeoData] = useState({lat:null,lng:null});
    

    And in return of your component, you should change that Marker only paint when geoData lat and lng are different to null (it would be when you receive data in response axios):

    return (
        <div>
          <Map center={[52.6376, -1.135171]} zoom={12}>
            <TileLayer
              url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
              attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            />
            {geoData.lat && geoData.lng && <Marker position={[geoData.lat, geoData.lng]} />}
          </Map>
    

    And in useEffect I recommend you to use promise with then and catch to improve user experience. Only in then you must to use setGeoData and overwrite properties lat and lng

    useEffect(() => {
          axios.get(
            "https://api.opencagedata.com/geocode/v1/json?q=United%20States&key={accessToken}&language=en&pretty=1"
          ).then(response => {
           // I expect in response object geometry, change by the correct route
           setGeoData(response.data.geometry);
          }).catch(err => {
            console.log("error",err);
          });
      }, []);
    

    -------- NEXT QUESTION --------

    If you want to edit styles of map.

    As you can see in docs in React-Leaflet: Link here

    You can add props like className or style.

    The result it would be

    <Map style={{width:"400px",height:"600px"}}>
    ...