Trouble with LiveView pushEvent to push map click back to server

I have gotten a mapboxgl js map on my site and when I click on the map I am able to see a console.log fine on JS side. I want to send an event back to liveview/server when the click happens with the coordinates. When I click and the code gets to this.pushEvent, I get this error: Uncaught TypeError: this.pushEvent is not a function in the JS console. Whats the right way to use pushEvent, do I need to import something to use it?

map_live.ex code

defmodule AppWeb.MapLive do
  use AppWeb, :live_view

  @impl true
  def mount(_params, _session, socket) do
    {:ok, socket}
  end

  def handle_event("selected_location", %{"location" => coords}, socket) do
    IO.puts(coords)
    {:noreply, socket}
  end

end

map_live.html.leex code

 <div id="map" phx-hook="MainMap"></div>

app.js relevant code

import mapboxgl from 'mapbox-gl';

let Hooks = {}
Hooks.MainMap = {

  mounted() {
    mapboxgl.accessToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

    const map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/outdoors-v11',
      center: [-122.4376, 37.7577],
      zoom: 8
    });

    map.on('click', function (e) {
      this.pushEvent("selected_location", { location: e.lngLat })
    });
  }
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, hooks: Hooks })
2 Likes

:wave:

Does

    const view = this;
    map.on('click', function (e) {
      view.pushEvent("selected_location", { location: e.lngLat })
    });

work?

3 Likes

Yeah, I’m guessing wherever that on method is coming from is rebinding this. You can either save this like the other poster suggested, or use a vanilla addEventListener instead. Your use of pushEvent is correct.

Yes that did work once I moved the const view = this; before the click function and then called view.pushEvent inside the function. Makes sense now, thank you for the help.