1

I am trying to remove a particular marker from the map, for that, I've written the below

  <button (click)="removeDriver(id)"></button>


  removeDriver(userId) {
      //remove from the array a particular user
    this.places = this.places.filter((user) => {
      return user.userId !== userId;
    });

    let currentDriverLocation;
    //the array elements are updated now, and the markers should be plotted again
    this.places.forEach((driver) => {
      currentDriverLocation = new google.maps.LatLng(driver.currentLocation.lat, driver.currentLocation.long);
           this.marker = new google.maps.Marker({ position: currentDriverLocation, map: this.map });
    })
  }

The array is updated with the new objects; however, no markers get deleted.

this.places array looks like the following:

    [{"userId":"khfdg999","currentLocation":{"lat":59.02922, "lng":-12.3932}},

     {"userId":"a85jfdo","currentLocation":{"lat":59.02922, "lng":-12.3932}}]
Folky.H
  • 1,164
  • 4
  • 15
  • 37
  • `The array is updated with the new objects; however, no markers get deleted.` That's because you aren't removing them. You need to remove them when you are filtering the array. You need to call `setMap(null)` – Adam Jenkins May 29 '17 at 14:02
  • Please take a look at this post https://stackoverflow.com/questions/16482949/google-map-api-removing-markers it has an answer where is described how to remove marker – Aleksandar Gajic May 29 '17 at 14:03
  • Can you please elaborate more? I've tried to call `this.marker.setMap(null)` before `filter()` but nothing changed... – Folky.H May 29 '17 at 14:09
  • For whatever reason, it wouldn't work for me unless the array that I was storing the Markers in was accessible from the Global/Module scope. I was using Vue and storing the Markers on an instance property of my component didn't work. – Fearnbuster May 18 '21 at 16:15

2 Answers2

2

In your case, you are duplicating existing marker (except the one to be removed).

To remove a marker from the map, you have to call:

marker.setMap(null);

For that, you need to keep a reference on each marker that you create and its associated "userId". It could be something like:

removeDriver(userId) {
  //remove from the array a particular user
  this.places = this.places.filter((user) => {
    return user.userId !== userId;
  });
  //remove from the markers a particular user
  if (this.markers[userId]) {
    this.markers[userId].setMap(null);
    this.markers[userId] = null;
  };
}

addDriver(lat, lng, userId) {
    this.places.push({
      userId: userId,
      currentLocation: {lat: lat, long: lng}
    });
    this.markers[userId] = new google.maps.Marker({ 
      position: new google.maps.LatLng(lat, lng),
      map: this.map
    });
}

And you only call displayMarkers after loading the drivers.

Grégory Bourgin
  • 912
  • 7
  • 18
1

My problem is kinda different. I have a lot of markers (around 300 markers) that loaded dynamically from back-end according to user's filter. Every time user change the filter I'd clear all the markers and re-draw new markers on the map. I've used the suggested method to populate all the drawn marker into an array (in my case it is an object). But several markers always failed to be deleted.

Apparently the setMap() is executed asynchronously by google map API. So it will introduces race condition we clear marker and then load marker very quickly and resulting some deleted markers still drawn on map.

The solution is move to-be-deleted markers to separate array (deleted_marker) then invoke setMap(null) on markers. Here are the codes:

function clearMarkers() {
      // loaded_markers is a global object or array that contains all drawn markers
      var deleted_marker = [];
      for (i in loaded_markers) {
        deleted_marker.push(loaded_markers[i]);
      }
      for (var i in deleted_marker) {
        deleted_marker[i].setMap(null);
      }
}
qatz
  • 163
  • 2
  • 12