I am having an issue with Experience Builder Developer Edition.
I have built a custom widget that creates and monitors Session Storage Variables. Then I have added a Windows EventListener to monitor the variables for change. The Session storage variables are used to set the definitionExpressions on the feature layers in the Web Map. It is working wonderfully.
The issue is that when the Browser window containing the ExpB App is resized beyond a certain threshhold it seems that the ExpB app is throwing a rerender event that ignores any settings that were set on the Map (including the layer definition expressions).
I tried to handle this by using another Windows Eventlistener that monitors Browser resizing. This works just fine until the ExpB (ExpB builtin Threshold?) is reached. The entire Web App seems to refresh with new DOM element placement. But this event removes all layer definitions, refreshes the Map and App DOMS. I cannot find a hook that will fire the useStates and/or Eventlisteners.
Does anybody know what is going on here?
Thanks for any info.
BobinTN
Solved! Go to Solution.
Depending on what Template or configurations you may be using, you may need to configure your widgets for every screen size. The broken Legend Widget is likely a different copy of the Legend Widget that was never configured.
Please make sure you are using the same custom widget for each layout size. You must select the widget from the Pending Tab, if you are on the New Tab, you will be adding a different copy of the widget.
Assuming you are using the same custom widget across all sizes and you are still having this problem, we may have a more fundamental issue. I believe you are correct that there is some sort of reload when switching between layout size breaks. I believe that crossing one of these breakpoints causes a top down re-render of all the React components. You may need to use an useEffect() function to re-capture your data after such an event. This is the useEffect syntax for a hook that runs on the first load of a component.
useEffect(() => {
console.log("Effect ran");
}, []) // the useEffect will now only be evoked once per render
If you are sending your data into session storage, I don't think it should be wiped by a re-render. And if all you are tracking is definitionExpressions, they should be retained on the feature layer.
What I think is happening here is you added your custom widget to one of the small screen size layouts, but not the larger layout.
When re-sizing, you crossed into the larger layout and your custom widget was put in the Pending list, so it no longer affects your application. If you can find your widget in the Pending list for the large screen sizes, drag it back into your application from there and see if that fixes your problem.
Hey Mr. Thompson
Thanks for responding.
I had/have been designing in the Large Screen Layout (and ignoring the other layouts).
When I changed layout design mode to medium or small my SessionStorage widget was removed to the Widget Pending area.
I have now added my SessionStorage widget onto the medium and small layouts. Saved project. But when I run the experience preview the issue still exists. When the App screen size switches from Large to Medium all map layer settings (definitionExpressions) set by my SessionStorage widget are lost.
Also the Legend Widget no longer shows any layers (but the ListLayer widget does). The experience is now broken and has to be reloaded.
I think you are right that the problem is tied to the ExpB switching Layouts based on browser window size. I would have thought that making sure that the SessionStorage widget is present in all three Layout types would fix the issue. But it appears that the ExpB auto layout switch is not such an elegant event. It is doing some type of 'reload' that does not take into account my SessionStorage Widget.
Do I need to capture the ExpB auto layout switch event in my code to reload my SessionStorage Widget?
Just for info, my SessionStorage Widget was/is based off of your posted URL Parameter widget. I appreciate your contributions/support to the ExpB Developer community.
BobinTN
Depending on what Template or configurations you may be using, you may need to configure your widgets for every screen size. The broken Legend Widget is likely a different copy of the Legend Widget that was never configured.
Please make sure you are using the same custom widget for each layout size. You must select the widget from the Pending Tab, if you are on the New Tab, you will be adding a different copy of the widget.
Assuming you are using the same custom widget across all sizes and you are still having this problem, we may have a more fundamental issue. I believe you are correct that there is some sort of reload when switching between layout size breaks. I believe that crossing one of these breakpoints causes a top down re-render of all the React components. You may need to use an useEffect() function to re-capture your data after such an event. This is the useEffect syntax for a hook that runs on the first load of a component.
useEffect(() => {
console.log("Effect ran");
}, []) // the useEffect will now only be evoked once per render
If you are sending your data into session storage, I don't think it should be wiped by a re-render. And if all you are tracking is definitionExpressions, they should be retained on the feature layer.
Hey Mr. Thompson,
Admittedly, I was totally ignorant about having to configure each layout (small, medium, large) for my experience (my only defense is that the product I am producing just deals with Desktop usage).
I have gone back through and moved the SessionStorage widget from the pending page of each layout back onto the experience layout. And have saved each layout configuration. When moving the SessionStorage widget from pending, all of the widget setting values are still there. I have tested (previewed) the experience in each layout configuration. The SS widget works in in each layout (small, medium, large) until the browser window is made smaller or larger enough to trigger the layout change. Then all the featurelayer settings are lost from the MapView. and the experience is broken until a manual reload of the preview.
*******************
export default function Widget (props: AllWidgetProps<IMConfig>) {
console.log('In Widget')
const [query, setQuery] = useState<FeatureLayerQueryParams>(null)
const [DLquery, setDLQuery] = useState<FeatureLayerQueryParams>(null)
const [DZquery, setDZQuery] = useState<FeatureLayerQueryParams>(null)
const [RZquery, setRZQuery] = useState<FeatureLayerQueryParams>(null)
const [HZquery, setHZQuery] = useState<FeatureLayerQueryParams>(null)
const [Dosequery, setDosequery] = useState<FeatureLayerQueryParams>(null)
const [mapReady, setMapReady] = useState(false)
const cityNameRef = useRef<HTMLInputElement>(null)
I would like to revise the above email.
The SS widget was bombing before the useEffect was able to execute during the ExpB breakpoints re-render event.
I found this out while moving around the above useStates (outside of widget, inside widget but outside useEffect, inside use Effect....)
I was able to place the above code in the useEffect initialization. This change allowed the SS widget to re-initalize during the breakpoint event and (basically but not perfectly) allowed the SS widget to keep running properly (not losing the QueryParams/expressionDefinitions).
I marked Mr. Thompsons explanation as the 'Accepted as Solution'. Thank you.
I will be starting another thread, shortly about a somewhat similar issue that I am having with the Toggling from one JimuMapView to another using the JimuMapView:JimuMapTool 'Select' map widget.
Stay tuned?
BobinTN