Select to view content in your preferred language

unbinding eventhandler from mapview

2157
4
Jump to solution
09-27-2022 11:02 AM
RiccardoKlinger
Frequent Contributor

As I am working with arcgis JS API 4.24. I want to bind an eventhandler to the view if a user clicks on the map:

mapStore.mapView?.on('click', (event) => {
            const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
            console.log('click event1: ', point);
            }

This eventhandler shall stay active as long as a condition is true. If the condition is false I would like to remove exactly this handler and I would like to only use the standard view on-click handler. I can disable the eventhandle exactly during its execution but I want to leave it active for the duration of the condition... the ad-hoc removal would look like:

export const clickhandler = (active: boolean): void => {
    const { mapStore } = Stores.getInstance();
    if (active) {
        const handler = mapStore.mapView?.on('click', (event) => {
            const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
            console.log('click event1: ', point);
            handler?.remove();
        });
    } else {
        console.log('click event1: ', 'disabled');
    }
};

I've seen some examples where they work with dojo/connect in arcgis JS API 3.x... Is there an equivalent in ArcGIS JS API 4?

0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Honored Contributor

@RiccardoKlinger you're very close. You just need to adjust your handler declaration and how you handle it a bit.

https://codepen.io/odoe/pen/bGMaJPW?editors=1001

let handler;
function myChange() {
  if (document.getElementById("check").checked) {
    // check if null
    if (handler) {
      return;
    }
    handler = view.on("click", (event) => {
      const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
      console.log(point);
    });
  } else {
    // remove and set to null
    handler?.remove();
    handler = null;
  }
}

View solution in original post

0 Kudos
4 Replies
ReneRubalcava
Honored Contributor

The ".on()" methods in the API return a Handler with a remove method you can use to remove the listener.

 

let handler;

handler = view.on("click", () => {
    console.log("click");
    handler && handler.remove();
});

 

 

Looks like something happened to the doc on this. I'll pass it on, thanks! 

Looks like it's not a specific type, it's just an Object with a remove() method as described here.

https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#on

0 Kudos
RiccardoKlinger
Frequent Contributor

Hi @ReneRubalcava ,

I've created this pen to visualize the problem: as long as the checkbox is checked I would like to log the coordinates which are clicked on the map. If I disable the checkbox I would like to stop the eventhandler.

https://codepen.io/butcher/pen/oNdpmML

Here is the code without the pen:

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>
      Intro to MapView - Create a 2D map | Sample | ArcGIS API for JavaScript
      4.24
    </title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.24/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.24/"></script>

    <script>
      require(["esri/Map", "esri/views/MapView"], (Map, MapView) => {
        const map = new Map({
          basemap: "topo-vector"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 4,
          center: [15, 65] // longitude, latitude
        });
        console.log(document.getElementById("check").checked)
        // $('#check').on('click',myFunction);
        var checkbox = document.getElementById("check");
        document.getElementById('check').onclick = function(){
          myChange();
        };
        function myChange(){
        if (document.getElementById("check").checked){
            var handler = view.on('click', (event) => {
            const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
         console.log(point)
              handler && handler.remove();
        });
         
        
      } else {
        handler?.remove();
      }
        }
        
      });
      
    </script>
  </head>

  <body>
    <div><input type="checkbox" id="check"></div>
    <div id="viewDiv"></div>
  </body>
</html>
0 Kudos
ReneRubalcava
Honored Contributor

@RiccardoKlinger you're very close. You just need to adjust your handler declaration and how you handle it a bit.

https://codepen.io/odoe/pen/bGMaJPW?editors=1001

let handler;
function myChange() {
  if (document.getElementById("check").checked) {
    // check if null
    if (handler) {
      return;
    }
    handler = view.on("click", (event) => {
      const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
      console.log(point);
    });
  } else {
    // remove and set to null
    handler?.remove();
    handler = null;
  }
}
0 Kudos
RiccardoKlinger
Frequent Contributor

thanks for the first candidate. As I am working with react/typescript I needed to add some // @ts-ignore lines but it is working like a charme:

import { Stores } from '../../../core/Stores';

// @ts-ignore
let handler;

export const clickHandler= (active: boolean): void => {
    const { mapStore } = Stores.getInstance();
    
    if (active) {
        // @ts-ignore
        if (handler) {
            return;
          }
          handler = mapStore.mapView?.on("click", (event) => {
            const point = `point: (${event.mapPoint.latitude}, ${event.mapPoint.longitude})`;
            console.log(point);
          });
        } else {
          // @ts-ignore
          handler?.remove();
          handler = null;
        }
};
0 Kudos