1
\$\begingroup\$

I made a service which saves places to localStorage after the user clicks the left mouse button on the map. When the user clicks the right mouse button on the marker, that marker is removed from localStorage.

var map,
    markersAll = [];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: -25.363, lng: 131.044}
  });

  renderMarkers();

  map.addListener('click', function(e) {
    var lat = e.latLng.lat();
    var lng = e.latLng.lng();    
    generateMarker(lat, lng);    
    //console.log(lat, lng);
  });  
}

function getMarkersFromLocalStorage() {
  return localStorage.markers ? JSON.parse(localStorage.markers) : [];
};

function addMarkerToLocalStorage(lat, lng) {
  var markers = getMarkersFromLocalStorage();
  markers.push({lat, lng});
  localStorage.markers = JSON.stringify(markers);
};

function removeMarkerFromLocalStorage(lat, lng) {
  var markers = getMarkersFromLocalStorage(),
      newMarkers = [];

  markers.forEach(function(marker) {
    if(marker.lat != lat && marker.lng != lng) {
      newMarkers.push({
        lat: marker.lat,
        lng: marker.lng
      });
    }
  });

  localStorage.markers = JSON.stringify(newMarkers);
};

function clearMarkers() {
  markersAll.forEach((marker) => {
    marker.setMap(null);
  });
};

function renderMarkers() {
  var markers = getMarkersFromLocalStorage();

  markers.forEach(function(marker) {
    //console.log(marker.lat, marker.lng);
    generateMarker(marker.lat, marker.lng);
  });
};

function generateMarker(lat, lng) {
  var marker = new google.maps.Marker({
    position: {lat: lat, lng: lng}
  }); 
  marker.setMap(map);
  markersAll.push(marker);
  addMarkerToLocalStorage(lat, lng);

  marker.addListener('rightclick', function(e) {
    var lat = e.latLng.lat();
    var lng = e.latLng.lng();
    //console.log('right click', lat, lng);
    clearMarkers();
    removeMarkerFromLocalStorage(lat, lng);
    renderMarkers();    
  });   

  return marker;
};
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map {
  height: 100%;
}
<div id="map"></div>

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The code looks like typical code that uses the Google Maps API. Nice work serializing the markers in localstorage.

I did notice that there doesn't appear to be any mechanism to prevent the user from adding one marker multiple times. You may need to change your data structure to one that associates keys with values (e.g. a (hash) Map, or use an object instead of an array).

Related to preventing markers from appearing multiple times in the array, there appears to be a bug: when the user removes a marker, all other markers get duplicated because after removeMarkersFromLocalStorage() is called, the call to renderMarkers() will call generateMarker() for each marker, which in turn adds the marker to the list again.

I would recommend that instead of adding a listener for rightclick to each marker, try to add the listener to the map. It doesn't appear that the callback run on the rightclick event utilizes any properties of the marker - just the latitude and longitude of the event. It may be the case that the Google Maps API and/or modern browsers have handled it but in general, one cause of memory leaks in Javascript is adding an event listener to a DOM element and then having that element removed. For more information on that topic , read 4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them - especially the section under the heading 2: Forgotten timers or callbacks.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.