teatzr
teatzr

Reputation: 69

Not able to move my marker using the library leaflet

I am working on react.js using the leaflet library and I would like when I click on the map moving the marker and not add a new marker. Here is my code :

import React from "react";
import {
  MapContainer,
  TileLayer,
  useMapEvents,
  MapConsumer
} from "react-leaflet";
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import icon from "./constants";
import "./styles.css";

export default function App() {
  function MyComponent() {
    const map = useMapEvents({
      click: (e) => {
        const { lat, lng } = e.latlng;
        L.marker([lat, lng], { icon }).addTo(map);
      }
    });
    return null;
  }

  return (
    <MapContainer
      center={[50.5, 30.5]}
      zoom={13}
      style={{ height: "100vh" }}
      // whenReady={(map) => {
      //   console.log(map);
      //   map.target.on("click", function (e) {
      //     const { lat, lng } = e.latlng;
      //     L.marker([lat, lng], { icon }).addTo(map.target);
      //   });
      // }}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <MapConsumer>
        {(map) => {
          console.log("map center:", map.getCenter());
          map.on("click", function (e) {
            const { lat, lng } = e.latlng;
            L.marker([lat, lng], { icon }).addTo(map);
          });
          return null;
        }}
      </MapConsumer>
    </MapContainer>
  );
}

You can find my code there : my code

Could you help me please ?

Thank you very much !

Upvotes: 0

Views: 668

Answers (2)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

This is expected behavior for a marker, per documentation:

draggable Boolean false Whether the marker is draggable with mouse/touch or not.

meaning:

L.marker([lat, lng], { icon, draggable: "true" }).addTo(map);

will make marker a draggable

To prevent a multiple markers on map click, you could consider a solution proposed in another answer or utilize once instead of on:

Behaves as on(…), except the listener will only get fired once and then removed.

Final example

 <MapContainer center={[50.5, 30.5]} zoom={13} style={{ height: "100vh" }}>
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <MapConsumer>
        {(map) => {
          map.once("click", function (e) {
            const { lat, lng } = e.latlng;
            L.marker([lat, lng], { icon, draggable: "true" }).addTo(map);
          });
          return null;
        }}
      </MapConsumer>
 </MapContainer>

Live demo

Upvotes: 0

Seth Lutske
Seth Lutske

Reputation: 10686

Yes, this can be done. Instead of creating a new marker every time, you can set the latlng of the existing marker:

<MapConsumer>
  {(map) => {
    let marker;
    map.on("click", function (e) {
      const { lat, lng } = e.latlng;
      if (marker) {
        marker.setLatLng([lat, lng]);
      } else {
        marker = L.marker([lat, lng], { icon }).addTo(map);
      }
    });
    return null;
  }}
</MapConsumer>

Working codesandbox

Upvotes: 1

Related Questions