'How to close all popups programmatically in mapbox gl?

So, I know that we have Marker.togglePopup() in Mapbox GL API. But can we close all popups programmatically?



Solution 1:[1]

The accepted answer didn't apply to my use case (I wasn't using a Marker). I was able to come up with a different solution by utilizing the mapbox's built-in event workflow. Hopefully this helps someone else.

Mapbox allows you to listen to events on the map (and manually trigger them). The documentation doesn't mention it, but you can use custom events.

Given you have a popup:

// Create popup and add it to the map
const popup = new mapboxgl.Popup({ offset: 37, anchor: 'bottom' }).setDOMContent('<h5>Hello</h5>').setLngLat(feature.geometry.coordinates).addTo(map);

// Add a custom event listener to the map
map.on('closeAllPopups', () => {
  popup.remove();
});

When you want to close all popups, fire the event:

map.fire('closeAllPopups');

Solution 2:[2]

Mapbox automatically uses the class .mapboxgl-popup for the popup. You can also add additional classes with options.className.

So, if you have jQuery available, just do:

$('.mapboxgl-popup').remove();

Or plain javascript:

const popup = document.getElementsByClassName('mapboxgl-popup');
if ( popup.length ) {
    popup[0].remove();
}

I'm pretty sure you can assume there's only ever one popup open. The default behavior seems to be that if one is open and a second item is clicked, the first popup is removed from the DOM completely when the second one opens. If your application allows multiple open popups somehow, you will need to loop through and remove each with plain js, instead of using the first item only.

Solution 3:[3]

I know it's an old question but I recently worked on Mapbox. As of mapbox-gl v2.3, mapboxgl.Popup has a closeOnClick property where if set to true, the popup disappears when you click away from the popup.

let popup = new mapboxgl.Popup({
  anchor: "top",
  closeOnClick: true,
});

map.on(
  "click",
  "location",
  (e) => {
    map.getCanvas().style.cursor = "pointer";

    let coordinates = e.features[0].geometry.coordinates.slice();

    popup
      .setLngLat(coordinates)
      .setHTML("what I want to display")
      .addTo(map);
  }
);

Alternatively, you can show the popup on "mouseenter" instead of on "click" and add a "mouseleave" event to remove the popup:

  map.on(
  "mouseleave",
  "location",
  () => {
    map.getCanvas().style.cursor = "";
     popup.remove();
  }
);

Solution 4:[4]

wrap your popup with React.StrictMode and closeOnClick={false}.

const [popup, setPopup] = useState<boolean>(false);
...
{popup && (
<React.StrictMode>
    <Popup longitude={52.001126260374704} latitude={34.906269171550214}
           anchor="bottom"
           onClose={() => {
               setPopup(false)
           }}
           closeOnClick={false}
    >
        You are here
    </Popup>
</React.StrictMode>
)}

Solution 5:[5]

Your error:

        <message>Uncaught TypeError: Cannot read property &apos;siteName&apos; of null</message>

It stated your content of siteName is empty. Are you sure your passing variable is the right name? Maybe you are passing Website instead of siteName?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dan Sterrett
Solution 2
Solution 3 m007
Solution 4 MRajaeiM
Solution 5 Iona Varga