Experience Builder Dev Edition 1.8.0
I have a custom widget where I use DataSourceManager to access a specific data source. The odd thing is all my code works fine when I use the Live View mode in Exp Builder but fails when I preview the app.
When I console DataSourceManager.getInstance() in Exp Builder I can see my data source in the DataSources object but when I do that in preview the data source is not there.
Is there something I need to do to force the data source to be available in preview?
@Danik-B Do you use DataSourceComponent in your widget? https://developers.arcgis.com/experience-builder/guide/use-data-source-in-widget/#read-and-display-t...
In builder, all data sources will be created automatically for the convenience of changing data setting. However, in preview, only data sources which are used will be created.
Hello,
could you elaborate on this some more? I think I am having the same issue. I am able to successfully use my widget in the experience builder developer environment, but once I try to preview my experience, my widget is unable to read my datasources. Below is a sample of my code. Line 21 seems to return undefined for the layerview datasource when previewing my experience, but in the builder mode, it works fine.
How can I fix this?
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>
);
};
Hi @PartyPelican ,
For performance reason, JimuLayerView will not automatically create data source. If data source has been created by some widgets, then JimuLayerView.getLayerDataSource() gets the data source. If the data source has not been created, you can create the data source through the asynchronous method JimuLayerView.createLayerDataSource().
The createLayerDataSource method worked for me, but I don't actually see this method documented by ESRI. I do see the DataSourceManager methods for creating a datasource but when trying to pass the layerDataSourceId to DataSourceManager.getInstance().createDataSource() I get the error that the datasource could not be created. Do you know why that is?
@PartyPelican It is expected DataSourceManager.getInstance().createDataSource() fails to create a layer data source. DataSourceManager needs a rootDataSourceId to know which map the layer belongs to.
We recommend using DataSourceManager.getInstance().createDataSourceByUseDataSource({ dataSourceId: layerDataSourceId, mainDataSourceId: layerDataSourceId, rootDataSourceId: mapDataSourceId }).