Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datasource not loading in experience builder preview. #193

Open
Party-Pelican opened this issue Oct 4, 2024 · 8 comments
Open

Datasource not loading in experience builder preview. #193

Party-Pelican opened this issue Oct 4, 2024 · 8 comments

Comments

@Party-Pelican
Copy link

I am working on a custom widget and my code works while in the builder mode of experience builder. However, whenever I preview my widget, the datasource is undefined. Is this by design? What causes this?

I appreiciate any help.

Screenshot 2024-10-03 221203
Screenshot 2024-10-03 221118

`import {
DataSource,
DataSourceManager,
React,
type AllWidgetProps,
} from "jimu-core";
import { type IMConfig } from "../config";
import { JimuLayerView, JimuMapView, JimuMapViewComponent } from "jimu-arcgis";
import { MouseEvent, useState } from "react";
import { Dropdown, DropdownButton, DropdownItem, DropdownMenu } from "jimu-ui";
import ConditionController from "./conditionController";
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";

const Widget = (props: AllWidgetProps) => {
const [dataSources, setDataSources] = useState<DataSource[]>([]);
const [selectedDataSource, setSelectedDataSource] = useState({
dataSource: null,
schema: null,
});

function onActiveViewChange(activeView: JimuMapView) {
if (activeView) {
activeView.whenAllJimuLayerViewLoaded().then((jimuLayerViews) => {
const dataSources = Object.values(jimuLayerViews).map((jimuLayerView) =>
jimuLayerView.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 (


QueryBuilder Widget

  {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>

);
};`

@qlqllu
Copy link
Collaborator

qlqllu commented Oct 8, 2024

For performance reasons, the data source is created on demand by the widget in runtime. Could you use the to create the data source?

@Party-Pelican
Copy link
Author

Party-Pelican commented Oct 9, 2024

I tried using the createDataSource method from the DataSourceManager instance but I get an error saying that the datasource couldn't be created.

image

function onActiveViewChange(activeView: JimuMapView) { if (activeView) { activeView.whenAllJimuLayerViewLoaded().then((jimuLayerViews) => { const layerViewDataSourceIds = Object.values(jimuLayerViews).map( (jimuLayerView) => jimuLayerView.layerDataSourceId ); layerViewDataSourceIds.forEach((id, i) => { DataSourceManager.getInstance() .createDataSource(id) .then((ds) => { console.log(ds); }); }); }); } else { setDataSources([]); } }

@qlqllu
Copy link
Collaborator

qlqllu commented Oct 9, 2024

The child data sources can't be created directly in the DatasourceManager, can you try the ?

@Party-Pelican
Copy link
Author

The child data sources can't be created directly in the DatasourceManager, can you try the ?

Can I try what?

@qlqllu
Copy link
Collaborator

qlqllu commented Oct 10, 2024

<DataSourceComponent/>, sorry the last content is not displayed.

@Party-Pelican
Copy link
Author

I dont want to use the DataSourceComponent because I want to pull all the datasources from the map widget selected. I did manage to get my code working by using jimuLayerView.createLayerDataSource() but I don't see this method documented by esri.

I would like to use the DataSourceManager.getInstance().createDataSource(jimuLayerView.layerDataSourceId) since it's documented but I can't seem to get it to work. Do you know why using this method doesn't work?

@qlqllu
Copy link
Collaborator

qlqllu commented Oct 14, 2024

jimuLayerView.createLayerDataSource(), you can use this method. We'll add more docs step by step in releases.

The reason why DataSourceManager.getInstance().createDataSource(jimuLayerView.layerDataSourceId) does not work is DataSourceManager can't create child data sources directly, child data sources are created by the root data sources. In this case, by the map data source.

Creating all data sources from a map is not a good practice; creating too many data sources may cause performance issues.

@Party-Pelican
Copy link
Author

What would be the proper way of creating child data sources? Should I continue to use the jimuLayerView.createLayerDataSource() method? Will the DataSourceManager be capable of creating child data sources in the future?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants