0

as far as I can tell everything works more or less as I intend it to, except removeMarkers which doesn't seem to work, despite being a very short and easy function. My code:

// Google Map
let map;

// Markers for map
let markers = [];

// Info window
let info = new google.maps.InfoWindow();


// Execute when the DOM is fully loaded
$(document).ready(function() {

// Styles for map
// https://developers.google.com/maps/documentation/javascript/styling
let styles = [

    // Hide Google's labels
    {
        featureType: "all",
        elementType: "labels",
        stylers: [
            {visibility: "off"}
        ]
    },

    // Hide roads
    {
        featureType: "road",
        elementType: "geometry",
        stylers: [
            {visibility: "off"}
        ]
    }

];

// Options for map
//     https://developers.google.com/maps/documentation/javascript/reference#MapOptions
let options = {
    center: {lat: 37.4236, lng: -122.1619}, // Stanford, California
    disableDefaultUI: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    maxZoom: 14,
    panControl: true,
    styles: styles,
    zoom: 13,
    zoomControl: true
};

// Get DOM node in which map will be instantiated
let canvas = $("#map-canvas").get(0);

// Instantiate map
map = new google.maps.Map(canvas, options);

// Configure UI once Google Map is idle (i.e., loaded)
google.maps.event.addListenerOnce(map, "idle", configure);

});


// Add marker for place to map
function addMarker(place)
{
// Create new marker
let latlng = new google.maps.LatLng(place.latitude, place.longitude);
let marker = new google.maps.Marker({
    position: latlng,
    map: map,
    title: place.place_name
});

// Get articles for the marker
$.getJSON("/articles", {geo: place.postal_code}, function(article_list) {
    content = "<ul>";
    for (let i = 0; i < article_list.length || i < 10; i++)
    {
        content += "<li><a target='_blank' href='" + article_list[i].link + 
"'>" + article_list[i].title + "</a></li>";
    }
    content += "</ul>";
});

// Add listener to marker
marker.addListener('click', function() {
    showInfo(marker, content);
});

// Add marker to markers array
markers.push(marker);
}


// Configure application
function configure()
{
// Update UI after map has been dragged
google.maps.event.addListener(map, "dragend", function() {

    // If info window isn't open
    // http://stackoverflow.com/a/12410385
    if (!info.getMap || !info.getMap())
    {
        update();
    }
});

// Update UI after zoom level changes
google.maps.event.addListener(map, "zoom_changed", function() {
    update();
});

// Configure typeahead
$("#q").typeahead({
    highlight: false,
    minLength: 1
},
{
    display: function(suggestion) { return null; },
    limit: 10,
    source: search,
    templates: {
        suggestion: Handlebars.compile(
            "<div>" +
            "<div>{{place_name}}, {{admin_name1}}, {{postal_code}}</div>" +
            "</div>"
        )
    }
});

// Re-center map after place is selected from drop-down
$("#q").on("typeahead:selected", function(eventObject, suggestion, name) {

    // Set map's center
    map.setCenter({lat: parseFloat(suggestion.latitude), lng:     parseFloat(suggestion.longitude)});

    // Update UI
    update();
});

// Hide info window when text box has focus
$("#q").focus(function(eventData) {
    info.close();
});

// Re-enable ctrl- and right-clicking (and thus Inspect Element) on Google     Map
// https://chrome.google.com/webstore/detail/allow-right-click/hompjdfbfmmmgflfjdlnkohcplmboaeo?hl=en
document.addEventListener("contextmenu", function(event) {
    event.returnValue = true; 
    event.stopPropagation && event.stopPropagation(); 
    event.cancelBubble && event.cancelBubble();
}, true);

// Update UI
update();

// Give focus to text box
$("#q").focus();
}


// Remove markers from map
function removeMarkers()
{
for (let i = 0; i < markers.length; i++)
{
    markers[i].setMap[null];
}
markers = [];
}


// Search database for typeahead's suggestions
function search(query, syncResults, asyncResults)
{
// Get places matching query (asynchronously)
let parameters = {
    q: query
};
$.getJSON("/search", parameters, function(data, textStatus, jqXHR) {

    // Call typeahead's callback with search results (i.e., places)
    asyncResults(data);
});
}


// Show info window at marker with content
function showInfo(marker, content)
{
// Start div
let div = "<div id='info'>";
if (typeof(content) == "undefined")
{
    // http://www.ajaxload.info/
    div += "<img alt='loading' src='/static/ajax-loader.gif'/>";
}
else
{
    div += content;
}

// End div
div += "</div>";

// Set info window's content
info.setContent(div);

// Open info window (if not already open)
info.open(map, marker);
}


// Update UI's markers
function update() 
{
// Get map's bounds
let bounds = map.getBounds();
let ne = bounds.getNorthEast();
let sw = bounds.getSouthWest();

// Get places within bounds (asynchronously)
let parameters = {
    ne: `${ne.lat()},${ne.lng()}`,
    q: $("#q").val(),
    sw: `${sw.lat()},${sw.lng()}`
};
$.getJSON("/update", parameters, function(data, textStatus, jqXHR) {

   // Remove old markers from map
   removeMarkers();

   // Add new markers to map
   for (let i = 0; i < data.length; i++)
   {
       addMarker(data[i]);
   }
});
};

Sorry if the format here is a bit tough regarding indentation, it's better in my code :P.

1

The removeMarkers function is really is no more than a line of code as below,simply passing a null to the setMapOnAll() function would suffice :

setMapOnAll(null);
10
  • Thanks for trying to help, that line of code is from the google documentation, that function is one they have created, I wrote the exact same thing in my code in removeMarkers. However, I accidentally used square brackets instead of regular: I wrote markers[i].setMap[null], and couldn't see it at the time. Today went over it all slowly again and saw it immediately. That's how the brain works I guess. Oct 22 '18 at 8:03
  • @sk.76 But that way you wouldn't actually delete the markers. Wouldn't the server run into memory problems, if it keeps creating more and more new markers, adding them to the markers list, and turning them off (i.e. hiding them)? Oct 22 '18 at 20:23
  • @Peter Pesch If you take a closer look into the setMapOnAll() function and the markers[] array and the removeMarker function,you will find that the markers[] array has been filled using addMarkers() and in the setMapOnAll() function, we actually are setting a null map on all those markers that are existing in the array. So, we create no new array marker elements here so,no memory issues.Essentially those preexisting markers at the time of updation are going to be hidden on a null map.
    – sk.76
    Oct 24 '18 at 16:12
  • @sk.76 Exactly. They are hidden. But in your version, they will still exist. Have another look at the documentation (developers.google.com/maps/documentation/javascript/examples/…). There it says about setMapOnAll(): "Removes the markers from the map, but keeps them in the array." Yonatan's version probably takes care of that by his line markers = [];. But your (one-line) version of removeMarkers() fails to do that ... Your markers array will keep growing. And you don't even set it's elements to NULL, so garbage collection will not work ... Oct 24 '18 at 16:36
  • By the way: Please do keep answering questions! Oct 24 '18 at 16:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .