We have an existing WAB app that has a Latitude box, Longitude box, and a 3rd box for structure height. It has a calculate button. You can either click on the button or click on the map and it will update the lat/long boxes and use the structure height value to run a brief analysis by getting a pixel value from a hosted raster image service layer.
It works great, we've used it for several projects with various tweaks over the years. But now we need to move it to Experience Builder. I was starting from scratch but realized that one of Robert Scheitlin's Feature Panel Widget did much of the base stuff we needed. So I started with it and heavily modified it. Commented out all of the attribute stuff. Replaced its disabled popup with a new one that returns the values from the raster. I recreated our lat/long/height boxes in the side panel.
I've got half the stuff I needed done. But I can't figure out how to pass variables or values around between parts of the code. Which is what I need to do to get the Calculate button to trigger the popup based on the entered lat/long.
In WAB I would have inspected the DOM elements and modified their values. But in React this is apparently Very Bad To Do. All of the stuff I've read says to use States and particularly 'useState', but I cannot get them to work.
Here's my lat/long/height boxes and calculate button. This code is in the render section. They all show up and exist. You can use the arrow buttons or enter numbers and those change the values in the boxes.
and my updateInputLat listener passes the event value succesfully
So in short, I have no idea how to define a global variable to pass around the... classes? functions? what are they even called? And I cant find any esri documentation on this. Eveyrthing I find for react doesnt work. I've tried declaring these variables all over the place and just cant figure it out.
Thanks for any help!
Solved! Go to Solution.
Check your casing in the this.setState function, the render method is using,
value={this.state.latTextBoxvalue}
while the setState function is using latTextBoxValue with a capital V.
this.setState({latTextBoxValue: event.target.value})
Sometimes these issue are frustratingly hard to see, especially when you've been staring at them for too long.
Check your casing in the this.setState function, the render method is using,
value={this.state.latTextBoxvalue}
while the setState function is using latTextBoxValue with a capital V.
this.setState({latTextBoxValue: event.target.value})
Sometimes these issue are frustratingly hard to see, especially when you've been staring at them for too long.
Augh! That was so helpful, thank you! I turned all the lower case values into Values where appropriate. Then it started recognizing stuff.
I've gotten it to where this is now valid, but I have some kind of incrementing mismatch.
I've gotten an initial value set here of 35 for the Latitude text box. Whatever I have the value to here appears to becoming the default
constructor (props) {
super(props)
this.state = {
jimuMapView: null,
totalNumOfLayers: 0,
setlatTextBoxValue: 0,
latTextBoxValue: 35,
updateInputLat: 0,
LongTextBoxValue: -86.9,
StructureHeightTextBoxValue: 0
}
Then later we get to the revised input listener
updateInputLat=(event)=>{
console.log("Latitude box change")
console.log("event.target.value : ");
console.log(event.target.value || "undefined"); //this does get the right value.
try{this.setState({latTextBoxValue: event.target.value})}
catch{console.log("line 319 failed")} //this is not erroring out?
try{console.log("this.state.latTextBoxValue: ")
console.log(this.state.latTextBoxValue) //succeeds but is 1 off from event.target value???
}
catch{console.log("line 325 failed")} //this is not erroring out?
but now, despite all the values working as variables... the values arent syncing up between event.target value and this.state.latTextBoxValue
Each red line in the screenshot below represents the console changes when clicking on the Latitude box's up arrows. Any ideas why latTextBoxValue is 1 off from event.target.value?
I've done it million times, the answer is right in front of you and you can't see it.
Re the next issue, setState is an asynchronus operation, so its likely the state has not updated before you try and log the result, you could try:
this.setState({latTextBoxValue: event.target.value},() =>{console.log("Updated state:" + this.state.latTextBoxValue)})
I wrote the above in the browser... I think I got the brackets in the right places. See if that works.
@RobertScheitlin__GISP wrote his widgets in the old class based React. React has been radically revamped in the last few years with function based components now being the commonly accepted norm. A few months ago, as part of the transition, React buried the class based documentation on their site. Here it is: https://legacy.reactjs.org/
State is not live data it is a stored unchanging value at the last re-render and setState does not update state until the next re-render. You should use setState to store values into the next render and do any other processing off of event.target.value directly.
I recently wrote a primer of basic React concepts here: https://community.esri.com/t5/experience-builder-tips-and-tricks/react-for-experience-builder-develo...