Select to view content in your preferred language

Getting currently selected Graphic: Graphic is empty object

240
2
a month ago
DavidDrennan
New Contributor II

Hello!

We are trying to calculate the distance/area of a user drawn graphic with the Sketch widget, which they've selected by clicking on the graphic on the map. However, it seems that the graphic is always an empty object.

The follow is a sample of what we have:

reactiveUtils.on(
  () => mapView,
    "click",
    (event) => {
        // graphicLayer is, you guessed it, a GraphicLayer
        mapView?.hitTest(event, { include: graphicLayer }).then(function (response) {
          const graphicHits = response.results?.filter(
            (hitResult) => hitResult?.type === "graphic"
          );

          console.log(graphicHits);

          if (graphicHits?.length > 0) {
            // hitObj, currGraphic, and currMeasurements are initially defined
            // somewhere else as null
            hitObj = graphicHits?.at(0);
            currGraphic = hitObj?.graphic;

            console.log(currGraphic); // <- will always show a blank object

            // simplyGeo just calls geometryEngine.simplify()
            const simplified = simplifyGeo(currGraphic);

            // creates an object with keys geodisc and planar that are
            // assigned a value based on the results of 
            // geometryEngine.geodesicArea / geometryEngine.geodesicLength or
            // geometryEngine.planarArea / geometryEngine.planarLength
            // respectively
            currMeasurements = getGraphicMeasurements(simplified);
          }
        });
      }
    );

 

Is there something else we have to do to get the graphic's data, instead of a blank object?

0 Kudos
2 Replies
JoelBennett
MVP Regular Contributor

Below is the code for the Sketch widget sample with lines 52-57 added to test this behavior, and it seems to be working as expected.  What version of the SDK are you using?

<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Sketch widget | Sample | ArcGIS Maps SDK for JavaScript 4.29</title>

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

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <script>
    require([
      "esri/widgets/Sketch",
      "esri/Map",
      "esri/layers/GraphicsLayer",
      "esri/views/MapView"
    ], (Sketch, Map, GraphicsLayer, MapView) => {
      const graphicsLayer = new GraphicsLayer();

      const map = new Map({
        basemap: "topo-vector",
        layers: [graphicsLayer]
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 5,
        center: [90, 45]
      });

      view.when(() => {
        const sketch = new Sketch({
          layer: graphicsLayer,
          view: view,
          // graphic will be selected as soon as it is created
          creationMode: "update"
        });

        view.ui.add(sketch, "top-right");
        
        view.on("click", function(evt) {
          view.hitTest(evt, {include:graphicsLayer}).then(function(response) {
            var graphic = response.results[0]?.graphic;
            console.info(graphic);
          });
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>
</html>

 

0 Kudos
DavidDrennan
New Contributor II

We're using the ES module, version 4.29.7. We tried on 4.29.10 and it made no difference.

If it helps, the sample code isn't 100% the same as what we have, as it's inside of a Vue 3 application. So as a better example, we have more or less the following in a Vue 3 script-setup tag:

 

const map = new Map({
  basemap: 'arcgis-light-gray',
});

const mapView = ref(null);

const graphicLayer = new GraphicsLayer({
  title: 'Graphics'
});

// some other code...

onMounted(() => {
    // https://vuejs.org/api/reactivity-advanced.html#markraw
    mapView.value = markRaw(useMapView({ map, ...mergedOpts.value }));
    mapView.value.when(() => {
      // bunch of other code here as well...
    });
});

// https://vuejs.org/guide/essentials/watchers.html#watcheffect
watchEffect(() => {
  if (mapView.value) {
    // all more or less the same as before
    reactiveUtils.on(
      () => mapView.value,
      "click",
      (event) => {
        mapView.value?.hitTest(event, { include: graphicLayer }).then(function (response) {
          const graphicHits = response.results?.filter(
            (hitResult) => hitResult?.type === "graphic"
          );
          console.log(graphicHits); // <- an empty object no matter what
          if (graphicHits?.length > 0) {
            // again, these variables are defined elsewhere
            hitObj = graphicHits?.at(0);
            currGraphic = hitObj?.graphic;
            console.log(currGraphic);
            const simplified = simplifyGeo(currGraphic);
            currMeasurements = getGraphicMeasurements(simplified);
          }
        });
      }
    );
  }
});

 

0 Kudos