Select to view content in your preferred language

jimuMapView evaluating as null despite loading in 1.12

764
2
07-12-2023 12:57 PM
JeffreyThompson2
MVP Regular Contributor

I have recently upgraded to developer edition 1.12 and I have encountered a bug which prevents one of my custom widgets from loading part of the time. I have traced the error back to jimuMapView evaluating as null despite the fact that it is actually loaded.

Screenshot 2023-07-12 142422.png

The following works 100% of the time in 1.11, but only about 75% of the time in 1.12.  My widget is loaded within a section that is not the active view when the page is loaded. The most reliable way to trigger the bug is to launch the page from the Preview in the builder mode. Reloading the Preview usually loads the widget correctly. Using the buttons within my custom widget will also clear the error and cause the rest of the widget to load correctly.

const viewManager = MapViewManager.getInstance()
const jimuMapView = viewManager.getJimuMapViewById(viewManager.getAllJimuMapViewIds()[0])

useEffect(() => {
   console.log('using effect')
   console.log('jimuMapView', jimuMapView)
   if (jimuMapView) {
     console.log('jimuMapView exists')
     reactiveUtils.whenOnce(() => jimuMapView.view.ready)
	.then(() => {
		setMapReady(true)
	}
     )
   })
  }
}, [jimuMapView])

The mapReady state variable triggers the child components which load a custom basemap gallery from the API.

 

GIS Developer
City of Arlington, Texas
0 Kudos
2 Replies
LeonAus
Regular Contributor

In the breaking changes for 1.12 they have a section describing how to wait for the jimuMapView. I use the same method as you've described but I'm thinking I should change my code to use whenJimuMapViewLoaded

0 Kudos
JeffreyThompson2
MVP Regular Contributor

The loading process is actually failing at the if statement before getting to the reactiveUtils line. I have tried using whenJimuMapViewLoaded and pushing jimuMapView into state, but neither changes the behavior of the code. Removing the if statement will cause the widget to crash completely if jimuMapView === null.

From my further investigations, I have determined that this problem is caused by a race condition between my widget and the map widget. If my widget loads before jimuMapView, jimuMapView will evaluate as null and my widget will not fully load. Ideally, I would pull jimuMapView from props and this race condition would not be an issue. Does anyone know how to do that?

I have a workaround involving setTimeout.

const viewManager = MapViewManager.getInstance()
const jimuMapView = viewManager.getJimuMapViewById(viewManager.getAllJimuMapViewIds()[0])
const [counter, setCounter] = useState(0)

const checkMap = () => {
  if (counter >= 10) {
     return
  } else {
     setTimeout(() => {
	console.log('from timeout')
	console.log(counter)
	setCounter(counter + 1)
     }, 1000)
   }
}

useEffect(() => {
   console.log('using effect')
   console.log('jimuMapView', jimuMapView)
   if (jimuMapView) {
     console.log('jimuMapView exists')
     jimuMapView.whenJimuMapViewLoaded().then(() => {
	console.log('map ready')
	setMapReady(true)
     })
   } else {
	checkMap()
   }
}, [counter])

 

Essentially if jimuMapView is null, wait a second and reload the widget. 

GIS Developer
City of Arlington, Texas
0 Kudos