Can some one see why I can not go past this line of code
When posting code in your questions, please use the "Insert/edit code sample" button
import { React, type AllWidgetProps } from 'jimu-core'
import { MapViewManager, JimuMapViewComponent, type JimuMapView } from 'jimu-arcgis'
import reactiveUtils from 'esri/core/reactiveUtils'
const { useEffect, useState } = React
let handler
const Widget = (props: AllWidgetProps<any>) => {
const viewManager = MapViewManager.getInstance()
const mapView = viewManager.getJimuMapViewById(viewManager.getAllJimuMapViewIds()[0])
const [jimuMapView, setJimuMapView] = useState<JimuMapView>(mapView)
const [mapReady, setMapReady] = useState(false)
useEffect(() => {
if (jimuMapView) {
reactiveUtils
.whenOnce(() => jimuMapView.view.ready)
.then(() => {
setMapReady(true)
alert('map ready')
if (props.state === 'OPENED') {
alert('open')
handler = (jmv: JimuMapView) => {
alert('test')
if (jmv) { alert('Event Handler ready') } else { alert('Not Ready') }
}
} else if (props.state === 'CLOSED') {
alert('closed')
}
}
)
}
}, [jimuMapView, props.state])
return (
<div className="widget-starter jimu-widget">
{
props.useMapWidgetIds &&
props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent
useMapWidgetId={props.useMapWidgetIds?.[0]}
onActiveViewChange={handler}
/>
)
}
{/* <p>Lat/Lon: {latitude} {longitude} </p> */}
<p><h9>Click on Map to get the coordinates </h9></p>
</div>
)
}
export default Widget
Ken:
Thanks for the tip
what do you think the issue is with this code?
You have defined the handler function, but you never actually call handler(). So you will not see the alerts, within the function. onActiveViewChange is called automatically when the map is changed (Not elements within the map, the entire map object.).
/* eslint-disable no-prototype-builtins */
/** @jsx jsx */
import { type AllWidgetProps, jsx } from 'jimu-core'
import { useEffect, useState } from 'react'
import { type IMConfig } from '../config'
import { MapViewManager, type JimuMapView, JimuMapViewComponent } from 'jimu-arcgis'
import reactiveUtils from 'esri/core/reactiveUtils'
import type Point from 'esri/geometry/Point'
import defaultMessages from './translations/default'
//const { useEffect, useState } = React
let activeViewChangeHandler
export default function (props: AllWidgetProps<IMConfig>) {
const [latitude, setLatitude] = useState<string>('')
const [longitude, setLongitude] = useState<string>('')
const [zoom, setZoom] = useState<number>(0)
const [scale, setScale] = useState<number>(0)
const [mapViewReady, setMapViewReady] = useState<boolean>(false)
const viewManager = MapViewManager.getInstance()
const mapView = viewManager.getJimuMapViewById(viewManager.getAllJimuMapViewIds()[0])
const [jimuMapView, setJimuMapView] = useState<JimuMapView>(mapView)
const [mapReady, setMapReady] = useState(false)
useEffect(() => {
if (jimuMapView) {
reactiveUtils
.whenOnce(() => jimuMapView.view.ready)
.then(() => {
setMapReady(true)
alert('map ready')
if (props.state === 'OPENED') {
alert('open')
activeViewChangeHandler = (jmv: JimuMapView) => {
alert('open2')
if (jmv) {
// When the extent moves, update the state with all the updated values.
jmv.view.watch('extent', evt => {
setLatitude(jmv.view.center.latitude.toFixed(3))
setLongitude(jmv.view.center.longitude.toFixed(3))
setScale(Math.round(jmv.view.scale * 1) / 1)
setZoom(jmv.view.zoom)
// this is set to false initially, then once we have the first set of data (and all subsequent) it's set
// to true, so that we can hide the text until everything is ready:
setMapViewReady(true)
})
// When the pointer moves, take the pointer location and create a Point
// Geometry out of it (`view.toMap(...)`), then update the state.
jmv.view.on('pointer-move', evt => {
const point: Point = jmv.view.toMap({
x: evt.x,
y: evt.y
})
setLatitude(point.latitude.toFixed(3))
setLongitude(point.longitude.toFixed(3))
setScale(Math.round(jmv.view.scale * 1) / 1)
setZoom(jmv.view.zoom)
setMapViewReady(true)
})
}
}
} else if (props.state === 'CLOSED') {
alert('closed')
}
}
)
}
}, [jimuMapView, props.state])
// activeViewChangeHandler = (jmv: JimuMapView) => {
// if (jmv) {
// // When the extent moves, update the state with all the updated values.
// jmv.view.watch('extent', evt => {
// setLatitude(jmv.view.center.latitude.toFixed(3))
// setLongitude(jmv.view.center.longitude.toFixed(3))
// setScale(Math.round(jmv.view.scale * 1) / 1)
// setZoom(jmv.view.zoom)
// // this is set to false initially, then once we have the first set of data (and all subsequent) it's set
// // to true, so that we can hide the text until everything is ready:
// setMapViewReady(true)
// })
// // When the pointer moves, take the pointer location and create a Point
// // Geometry out of it (`view.toMap(...)`), then update the state.
// jmv.view.on('pointer-move', evt => {
// const point: Point = jmv.view.toMap({
// x: evt.x,
// y: evt.y
// })
// setLatitude(point.latitude.toFixed(3))
// setLongitude(point.longitude.toFixed(3))
// setScale(Math.round(jmv.view.scale * 1) / 1)
// setZoom(jmv.view.zoom)
// setMapViewReady(true)
// })
// }
// }
const sections = []
sections.push(
<span>
{defaultMessages.latLon} {latitude} {longitude}
</span>
)
if (props.config.showZoom) {
sections.push(<span>Zoom {zoom.toFixed(0)}</span>)
}
if (props.config.showScale) {
sections.push(<span>Scale 1:{scale}</span>)
}
// We have 1, 2, or 3 JSX Elements in our array, we want to join them
// with " | " between them. You cannot use `sections.join(" | ")`, sadly.
// So we use array.reduce(...) to return an array of JSX elements.
const allSections = sections.reduce((previousValue, currentValue) => {
return previousValue === null
? [currentValue]
: [...previousValue, ' | ', currentValue]
}, null)
return (
<div className="widget-get-map-coordinates jimu-widget m-2">
{props.hasOwnProperty('useMapWidgetIds') &&
props.useMapWidgetIds &&
props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent
useMapWidgetId={props.useMapWidgetIds?.[0]}
onActiveViewChange={activeViewChangeHandler}
/>
)}
{/* Only show the data once the MapView is ready */}
<p>{mapViewReady ? allSections : defaultMessages.latLonWillBeHere}</p>
</div>
)
}
Jeffry:
modified the get-map-coordinates-function program, but still getting the same issue here
activeViewChangeHandler = (jmv: JimuMapView) => {
when uncomment the original code and debug, any time i hover over the map, it goes to this code, but not when i use the useEffect function, any help will be greatly appreciated
Pedro
activeViewChangeHandler should not be defined within the useEffect function and should only be used for necessary effects when the map changes, usually just redefining the mapView. If your widget does not work with multiple maps, activeViewChangeHandler will never be called. You should delete the definition of activeViewChangeHadler from within the useEffect function, but keep its contents to set up your eventListeners. As written, your widget operates something like this: