Siri
Siri

Reputation: 129

How to dynamically set center of Map : Openstreetmap

I'm using openstreetmap and can't set the center of the map dynamically.

Below is my code.

function Map({ locations }) {
  return (
    <MapContainer
      center={
        locations.length > 0 && [parseFloat(locations[0].long), parseFloat(locations[0].lang)]
      }
      zoom={15}
      scrollWheelZoom={false}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      {locations.length &&
        locations.map((lo) => (
          <Marker key={lo.locationId} position={[lo.long, lo.lang]}>
            <Popup>text</Popup>
          </Marker>
        ))}
    </MapContainer>
  );
}

Example locations array:

[{locationId: 1, name: 'aa', long: '111.000', lang: '125.00'}, ...]

The error is

Uncaught TypeError: Cannot read properties of null (reading 'lat')
    at Object.project (Projection.SphericalMercator.js:22:1)
    at Object.latLngToPoint (CRS.js:28:1)
    at NewClass.project (Map.js:980:1)
    at NewClass._getNewPixelOrigin (Map.js:1503:1)
    at NewClass._move (Map.js:1222:1)
    at NewClass._resetView (Map.js:1182:1)
    at NewClass.setView (Map.js:206:1)
    at MapContainer.js:32:1
    at commitAttachRef (react-dom.development.js:23645:1)
    at commitLayoutEffectOnFiber (react-dom.development.js:23503:1)

Other Ways: I tried below:

let long, lang;
  if (locations.length > 0) {
    long = parseFloat(locations[0]?.long);
    lang = parseFloat(locations[0]?.lang);

    console.log(typeof [long, lang]); // prints -> Object
    console.log([long, lang]); // prints -> [111.00, 233.00] // gets data
  }

and I use long and lang in center props like center={[long, lang]}. But same error.

I'm using react and react-leaflet.

Upvotes: 0

Views: 473

Answers (1)

JeanJacquesGourdin
JeanJacquesGourdin

Reputation: 1843

I think your problem comes from the definition of center

function Map({ locations }) {
  return (
    <MapContainer
      center={
        ( locations && locations.length > 0 ) ? 
         [parseFloat(locations[0].long), parseFloat(locations[0].lang)]
         : 
         [0, 0]}
      zoom={15}
      scrollWheelZoom={false}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      {locations.length &&
        locations.map((lo) => (
          <Marker key={lo.locationId} position={[lo.long, lo.lang]}>
            <Popup>text</Popup>
          </Marker>
        ))}
    </MapContainer>
  );
}

With the way you did locations.length > 0 && ... it can put a false instead of an interpretable center like [0, 0]

Upvotes: 1

Related Questions