Hello, I have a custom widget that controls a map widget in my Experience Builder app. It essentially does 2 fetches on render that grab the web map portal ID associated with the user's company. it then replaces the web map in the map widget with the web map having that portal ID. I have a placeholder map with the proper extent but no content pre-loaded into the widget settings MapWidgetSelector.
It all works fine, but there is some annoying pop-in that i am running into, as it seems I can only access the JimuMapView object from that map widget once the placeholder map has loaded. essentially, the map loads, then we get a flash as it changes the web map. you can see it in the gif, below. notably, it only happens on faster connections, which is why i had to use such a fast-moving gif.
here is the code I am using
import { React, AllWidgetProps, jsx, SessionManager } from "jimu-core";
import { IMConfig } from "../config";
import { JimuMapViewComponent, JimuMapView } from "jimu-arcgis";
import WebMap from "esri/WebMap";
import FeatureLayer from "esri/layers/FeatureLayer";
const { useState, useEffect } = React;
function Widget(props: AllWidgetProps<IMConfig>) {
const [jimuMapView, setJimuMapView] = useState<JimuMapView>();
const [userMapId, setUserMapId] = useState(null);
const sessionManager = SessionManager.getInstance();
const activeViewChangeHandler = (jmv: JimuMapView) => {
// update the map widget to a different web map and
// store the JimuMapView in a state variable
if (jmv) {
console.log("JMV: ", jmv);
jmv.view.map = new WebMap({
portalItem: { id: userMapId },
});
setJimuMapView(jmv);
}
};
useEffect(() => {
async function getUserMap(): Promise<void> {
//...fetch the portalId of the web map associated
//...with the user's company and save it to the
//...webMapId constant
setUserMapId(webMapId);
console.log("updating user map id");
}
getUserMap();
}, []);
let content;
if (
props.useMapWidgetIds &&
props.useMapWidgetIds.length === 1 &&
props.config.userType &&
userMapId
) {
content = (
<div style={{ pointerEvents: "none", display: "none" }}>
<JimuMapViewComponent
useMapWidgetId={props.useMapWidgetIds?.[0]}
onActiveViewChange={activeViewChangeHandler}
/>
</div>
);
} else {
//show nothing otherwise
content = null
}
return <>{content}</>;
}
export default Widget;
Are there any suggestions as to how i could eliminate this pop-in? Ideally, I would just have the loading icon until the new map is loaded. I can't put a widget on top of the map widget because it won't let me pan the map if I do. EXB seems to insert some outer divs outside your actual components, and I can't seem to access them to apply pointer-events:none to the outer divs easily.
Thanks again for all your help!
I found a solution that didn't involve any javascript, actually.
I set the basemap of my placeholder map to have a transparency of 100% and turned off the reference layer.
then, I made the background color of my controller widget the same as the empty map frame, #0f0f0f.
I simply positioned the controller widget underneath the map widget (not inside), and made it the same size.
the end result is below
it's not an ideal solution, that would involve a loading screen until the new map is fully rendered. but this is acceptable enough for my clients.
Can you able to select any feature after webmap change? Actually I'm facing issue, i can't select any feature after webmap change. Any help on this?