I'm trying to build a custom widget that gets the coordinates of a map when the mouse is clicked and adds it to a graphics layer called gLayer. In the return statement, I added a button with an onClick event that calls a function named clearResults. The clearResults function runs gLayer.removeAll(), which I think should clear all features that were previously added to gLayer. New features are added to the layer without issue, but when I click the button to clear the layer, nothing happens. Can anyone inspect my code and help me figure out what the issue is?
Thanks in advance!
/** @jsx jsx */
import { React, WidgetState, type AllWidgetProps, jsx, getAppStore } from "jimu-core"
import { JimuMapViewComponent, type JimuMapView } from "jimu-arcgis"
import { Button } from 'jimu-ui'
import { SimpleLineSymbol, SimpleMarkerSymbol } from "esri/symbols"
import Point from 'esri/geometry/Point'
import Color from "esri/Color"
import Graphic from "esri/Graphic"
import GraphicsLayer from "esri/layers/GraphicsLayer"
const { useState } = React
export default function Widget (props:AllWidgetProps<any>) {
const[latitude, setLatitude] = useState<string>('Click a point on the map. Coordinates will appear here.')
const[longitude, setLongitude] = useState<string>('')
var gLayer = new GraphicsLayer()
const addGraphic = (latitude:number, longitude:number) => {
var point = new Point({
latitude: latitude,
longitude: longitude
})
var outline = new SimpleLineSymbol({
color: new Color([255,255,255,0.85]),
width: 1.5,
style: "solid"
})
var pointSymbol = new SimpleMarkerSymbol({
type: "simple-marker",
style: "triangle",
outline: outline,
color: new Color([255,53,42,1000]),
size: 18
})
var attributes = {
Latitude: latitude.toFixed(5),
Longitude: longitude.toFixed(5),
}
gLayer.add(new Graphic({
geometry: point,
symbol: pointSymbol,
attributes: attributes,
popupTemplate: {
title: "Coordinates",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "Latitude",
label: "Latitude"
},
{
fieldName: "Longitude",
label: "Longitude"
}]
}]
}
},
)
)
}
const activeViewChangeHandler = (jmv:JimuMapView) => {
var widgetState = WidgetState.Closed
if(jmv) {
jmv.view.map.add(gLayer)
jmv.view.on('click', (evt) => {
widgetState = getAppStore().getState().widgetsRuntimeInfo[props.id].state
if (widgetState === WidgetState.Opened) {
const point: Point = jmv.view.toMap({
x: evt.x,
y:evt.y
})
setLatitude("Latitude: " + point.latitude.toFixed(5))
setLongitude("Longitude: " + point.longitude.toFixed(5))
addGraphic(point.latitude, point.longitude)
}
})
}
}
const clearResults = () => {
gLayer.removeAll()
}
return <div className="widget-starter jimu-widget" style={{ overflow: "auto"}}>
{props.useMapWidgetIds && props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent useMapWidgetId={props.useMapWidgetIds?.[0]} onActiveViewChange={activeViewChangeHandler} />
)}
<p>{latitude}
<br/>{longitude}</p>
<div><Button onClick={clearResults} size="default">Clear Results</Button></div>
</div>
}
Solved! Go to Solution.
You should use a ref instead of a plain variable to store the "gLayer".
const gLayer = useRef(new GraphicsLayer())
gLayer.current.add(...)
glayer.current.removeAll()
In React, a plain variable "gLayer" is a new one in every render.
You should use a ref instead of a plain variable to store the "gLayer".
const gLayer = useRef(new GraphicsLayer())
gLayer.current.add(...)
glayer.current.removeAll()
In React, a plain variable "gLayer" is a new one in every render.
Thanks, that was indeed my issue. I had a feeling it might have something to do with how I was storing the layer, but I'm still new to using React so I'm still learning some of the concepts with it.
Much appreciated!