Hello,
I was wondering if anyone has experienced/fixed this issue. My widget works as expected when in experience builder developer edition. However, when viewing the experience in preview mode, my datasources don't seem to load and the widget throws an error. Line 21 is where the datasource for each layerview should be returned, this doesn't seem to work in preview mode.
Anyone run into this issue before? I appreciate any help!
import { DataSource, React, type AllWidgetProps } from "jimu-core";
import { type IMConfig } from "../config";
import { JimuMapView, JimuMapViewComponent } from "jimu-arcgis";
import { MouseEvent, useState } from "react";
import { Dropdown, DropdownButton, DropdownItem, DropdownMenu } from "jimu-ui";
import ConditionController from "./conditionController";
const Widget = (props: AllWidgetProps<IMConfig>) => {
const [dataSources, setDataSources] = useState<DataSource[]>([]);
const [selectedDataSource, setSelectedDataSource] = useState({
dataSource: null,
schema: null,
});
function onActiveViewChange(activeView: JimuMapView) {
console.log(activeView);
if (activeView) {
activeView.whenAllJimuLayerViewLoaded().then(() => {
const layerViews = activeView.getAllJimuLayerViews();
const dataSources = layerViews.map((layerView) => {
return layerView.getLayerDataSource();
});
setDataSources(dataSources);
});
} else {
setDataSources([]);
}
}
function handleDataSourceSelection(mouseEvent: MouseEvent<any, MouseEvent>) {
const ds = dataSources.find(
(ds) => ds.id === (mouseEvent.target as HTMLInputElement).value
);
setSelectedDataSource({ dataSource: ds, schema: ds.getSchema() });
}
return (
<div className="widget-demo jimu-widget m-2">
<p>QueryBuilder Widget</p>
{dataSources.length > 0 && (
<Dropdown activeIcon menuItemCheckMode="singleCheck" menuRole="listbox">
<DropdownButton>
{selectedDataSource.schema?.label || "Select a Datasource"}
</DropdownButton>
<DropdownMenu>
{dataSources.length > 0 &&
dataSources.map((dataSource) => {
return (
<DropdownItem
active={dataSource.id === selectedDataSource.dataSource?.id}
value={dataSource.id}
key={dataSource.id}
onClick={handleDataSourceSelection}
>
{dataSource.getSchema().label}
</DropdownItem>
);
})}
</DropdownMenu>
</Dropdown>
)}
{selectedDataSource.schema && selectedDataSource.schema.fields && (
<ConditionController
fields={Object.keys(selectedDataSource.schema.fields).map(
(k) => selectedDataSource.schema.fields[k]
)}
key={selectedDataSource.dataSource?.id}
/>
)}
<JimuMapViewComponent
useMapWidgetId={props.useMapWidgetIds?.[0]}
onActiveViewChange={onActiveViewChange}
/>
</div>
);
};
Solved! Go to Solution.
Hope this helps people having the same issue but apparently datasources are created on demand, they're not all loaded by default. The solution is to use jimuLayerView.createLayerDataSource(). You can read about it here:
https://github.com/Esri/arcgis-experience-builder-sdk-resources/issues/193
Try putting a console log between line 17 and 18. Sometimes it takes several microseconds for a complex object to write to memory, so activeview might be evaluating false at the if statement, but the console in the browser will show the full object after it is loaded. This kind of problem can be very confusing since your console is lying to you. Before the if statement, I think you need a delay function like setTimeout or reactiveUtils. This one should get you into the if.
reactiveUtils
.whenOnce(() => activeview.view.ready)
.then(() => {
if(activeView){...}
}
)
I gave it a try, but had no luck, Its bizarre, it works in the builder view of experience builder, but fails in preview.
Another thing to keep in mind is that the onActiveViewChange() function only activates when the jimuMapView is changed, as in the entire object is totally replaced. I think this function should be called when the project loads as it goes from undefined to defined, but it's possible that the function is not being called. My widgets almost always have an useEffect() function similar to this.
useEffect(() => {
//Once the map is loaded and ready add the initially active layers
if (jimuMapView) {
reactiveUtils
.whenOnce(() => jimuMapView.view.ready)
.then(() => {
//stuff to do when the widget loads
}
)
}
}, [jimuMapView])
I am running into the same issue. Mine is a widget that was developed in ArcGIS Experience Builder Dev Edition version 1.12. The original installation was on an ArcGIS Enterprise 11.2 Portal, and everything worked well. The problem only came up once the ArcGIS Enterprise system was upgraded to 11.3. There are some breaking changes noted for data sources under the jimu-core header in the 1.14 Experience Builder version associated with AGE 11.3 https://developers.arcgis.com/experience-builder/guide/1.14/whats-new/#breaking-changes. I'm not yet seeing why this would result in the data sources being defined in the Builder view context, and then fall apart in the context when the app is previewed or launched... I will post a solution if I find one though!
@TimWestern any chance you can provide insights here?
Hope this helps people having the same issue but apparently datasources are created on demand, they're not all loaded by default. The solution is to use jimuLayerView.createLayerDataSource(). You can read about it here:
https://github.com/Esri/arcgis-experience-builder-sdk-resources/issues/193