AlexLavoie42 / Nuxt-Mapbox

Elegant Mapbox integration with Nuxt
81 stars 11 forks source link

`MapboxDefaultPopup` HTML doesn't react to changes #37

Closed aliraza944 closed 1 year ago

aliraza944 commented 1 year ago

My Problem

I have a MapboxLayer of some geo JSON data containing properties that I want to show on the MapboxDefaultPopup. I have added an event listener called Mouseover on the layer. As the mouse moves from one polygon to another I want to show the properties on the popup of that polygon on which the mouse is hovering.
It only shows the default popup with just one polygon and does not display for the other.

My Code

Here is the MapboxLayer that I have implemented

<MapboxLayer
      :layer="{
        source: 'data',
        id: 'geojson-layer',
        type: 'line',
        paint: {
          'line-color': '#0052cc',
          'line-width': 2,
        },
      }"
      @mouseover="(e) => handleMouseMove(e)"
    />

The popup component has dynamic lat langs based on the mouse position

<MapboxDefaultPopup
        popup-id="popup1"
        :lnglat="hoverInfo.lngLat"
        :offset="[0, -10]"
        :options="{
          closeOnClick: false,
        }"
      >
        <span class="test">Hello World! {{ hoverInfo.lngLat[0] }}</span>
      </MapboxDefaultPopup>

My handleMouseMove function just sets the lat langs for the popup

const handleMouseMove = (e) => {
 // hoverInfo.value = null;
  hoverInfo.value = {
    lngLat: [e.lngLat.lng, e.lngLat.lat],
  };
};

Desired Outcome

I want to show the popup dynamically for the polygon on which the mouse pointer is.

AlexLavoie42 commented 1 year ago

Please leave a minimum reproduction using the playground

aliraza944 commented 1 year ago

Please leave a minimum reproduction using the playground

I have added my code to the playground. You can clearly see that it does not changes the latLang I am trying to print. Also the popup dose not shift from the one polygon to another very often.

AlexLavoie42 commented 1 year ago

Please save a copy and provide a link. Any changes you make do not reflect on the original playground

aliraza944 commented 1 year ago

Please save a copy and provide a link. Any changes you make do not reflect on the original playground

Sorry forgot here is the link https://stackblitz.com/edit/github-hunxbd-hw7dfm?file=playground%2Fpages%2Findex.vue

AlexLavoie42 commented 1 year ago

There are a couple different problems here. For one, the html inside the popup cannot be reactive at the moment (similar issue to #38), I am hoping to have a workaround for both of these issues at some point. However, the only way to actually update the html right now is to replace the html string in the popup instance with setHTML on the popup instance (see #38 for accessing the popup instance).

As for the "slow" updating, that is because mouseover event is only called when you initially hover over a polygon. If you want handleMouseMove every time the mouse moves you should use mousemove instead.

aliraza944 commented 1 year ago

The internal $mapboxPopupInstances is returning undefined. Can you please share an example with the defineMapboxPopup cause I don't know where to set its templateRef. I couldn't quite understand it from the DOCS

AlexLavoie42 commented 1 year ago

Make sure you are accessing $mapboxPopupInstances after the map is loaded, the popup will not be created at setup

templateRef in defineMapboxPopup is a ref for HTML you want to put inside the popup. https://vuejs.org/guide/essentials/template-refs.html

aliraza944 commented 1 year ago

So the ref will be assigned to the MapboxDefaultPopup component?

AlexLavoie42 commented 1 year ago

No the ref will be assigned to whatever HTML you want to add to the popup. If you are using defineMapboxPopup, you can no longer use the default MapboxDefaultPopup component, you have to make your own component.

I highly recommend using the default popup instead and accessing the instance with $mapboxPopupInstances. Make sure you are indexing the correct popup ID, and you access the popup instance after the map load (useMapbox callback should work for this).

AlexLavoie42 commented 1 year ago

Fixed in #45