Invalid LngLat object: (NaN, NaN) in react js , "Mapbox"

Viewed 1003

The project concept is to get geolocation and showing Mapbox map using API...

import ReactDOM from "react-dom";
import React, { useRef, useEffect } from "react";
import { geolocated } from "react-geolocated";
import mapboxgl from "mapbox-gl";
import fetchFakeData from "./api/fetchFakeData";
import Popup from "./components/Popup";
import "./App.css";

mapboxgl.accessToken ="pk.eyJ1IjoiamFja3Nvbi1rYXNpIiwiYSI6ImNrbzdsaDJvNTFvc3Eycm9pdTRxYmRxZjUifQ.BzA0w0U7lP0Ka3FcKkI_1Q";

const App = (props) => {
const mapContainerRef = useRef(null);
const popUpRef = useRef(new mapboxgl.Popup({ offset: 15 }));

// initialize map when component mounts

useEffect(() => {
const map = new mapboxgl.Map({
  container: mapContainerRef.current,
  // See style options here: https://docs.mapbox.com/api/maps/#styles
  style: "mapbox://styles/mapbox/streets-v11",
  center: [props.lat, props.long],
  zoom: 12.5
});

// add navigation control (zoom buttons)

map.addControl(new mapboxgl.NavigationControl(), "bottom-right");

map.on("load", () => {
  // add the data source for new a feature collection with no features
  map.addSource("random-points-data", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: []
    }
  });

// now add the layer, and reference the data source above by name

  map.addLayer({
    id: "random-points-layer",
    source: "random-points-data",
    type: "symbol",
    layout: {
      // full list of icons here: https://labs.mapbox.com/maki-icons
      "icon-image": "bakery-15", // this will put little croissants on our map
      "icon-padding": 0,
      "icon-allow-overlap": true
    }
  });
});

map.on("moveend", async () => {
  // get new center coordinates
  const { lng, lat } = map.getCenter();
  // fetch new data
  const results = await fetchFakeData({ longitude: lng, latitude: lat });
  // update "random-points-data" source with new data
  // all layers that consume the "random-points-data" data source will be updated automatically
  map.getSource("random-points-data").setData(results);
});

// change cursor to pointer when user hovers over a clickable feature
map.on("mouseenter", "random-points-layer", (e) => {
  if (e.features.length) {
    map.getCanvas().style.cursor = "pointer";
  }
});

// reset cursor to default when user is no longer hovering over a clickable feature
map.on("mouseleave", "random-points-layer", () => {
  map.getCanvas().style.cursor = "";
});

// add popup when user clicks a point
map.on("click", "random-points-layer", (e) => {
  if (e.features.length) {
    const feature = e.features[0];
    // create popup node
    const popupNode = document.createElement("div");
    ReactDOM.render(<Popup feature={feature} />, popupNode);
    // set popup on map
    popUpRef.current
      .setLngLat(feature.geometry.coordinates)
      .setDOMContent(popupNode)
      .addTo(map);
  }
});

// clean up on unmount
return () => map.remove();
}, []); // eslint-disable-line react-hooks/exhaustive-deps

return <div className="map-container" ref={mapContainerRef} /> 
};

export default geolocated({
positionOptions: {
enableHighAccuracy: false
},
userDecisionTimeout: 5000
})(App);

class Gps extends React.Component {
constructor() {
super();

this.state = {
  latitude: "",
  longitude: ""
};

this.getMyLocation = this.getMyLocation.bind(this);
}

componentDidMount() {
this.getMyLocation();
}

getMyLocation() {
const location = window.navigator && window.navigator.geolocation;

if (location) {
  location.getCurrentPosition(
    (position) => {
      this.setState({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      });
    },
    (error) => {
      this.setState({
        latitude: "err-latitude",
        longitude: "err-longitude"
      });
    }
  );
}}

render() {
const { latitude, longitude } = this.state;

return (
  <div>
    <App lat={latitude} long={longitude} />
  </div>
);
}
}

please see this link "codesandbox" : https://codesandbox.io/s/determined-river-7dt0h?file=/src/App.js

props didn't work.

see this lines:

  1. center: [props.lat, props.long]

  2. <App lat={latitude} long={longitude} / >

screenshot

1 Answers

The Problem

The Lat and Lng were initialized to an empty string, but the center property is expecting an array of numbers.

Solution

In Gps component, initialize the lat and long state values to a number as opposed to an empty string

this.state = {
  latitude: 38.8951,
  longitude: -77.0364
};
Related