Data sources define how your widget accesses data. There are a variety of things you may want to do with data sources, each of which are detailed below.
- Select a data source in the widget settings
- Read and display the data in the widget runtime
- Filter or query data based on user input
- Handle selection on data
- Sync the data source with the ArcGIS Maps SDK for JavaScript feature object
- Your widget may need to generate an output data source
- Your widget may need to publish a message
Note: when you see the app
variable used in this guide, it refers to the app config JSON object. For ArcGIS Online or Enterprise edition, the app config JSON is saved as item data; For developer edition, it is saved under server/public/apps/[app
(published version) or server/public/apps/[app
(draft version).
Select a data source in the widget settings
To select a data source in the widget settings, you should use the Data
component.
Experience Builder supports multiple types of data sources.
These data sources are in two packages: jimu-core
and jimu-arcgis
, see DataSourceTypes from jimu-core
and Data
from jimu-arcgis
.
The data sources in jimu-arcgis
depend on the ArcGIS Maps SDK for JavaScript, and the data sources in jimu-core
do not.
To use the Data
component, you must set the data source types that the widget supports through the types
prop. After you select a data source, you can get the selected data sources through the o
callback. In the o
callback, you need to call props.on
to save the selected data sources into the app
(app
).
If the user adds a new data source, the newly-added data source is saved in app
. See this sample widget.
<DataSourceSelector
types={Immutable([AllDataSourceTypes.FeatureLayer])}
useDataSources={props.useDataSources}
useDataSourcesEnabled={props.useDataSourcesEnabled}
onToggleUseDataEnabled={onToggleUseDataEnabled}
onChange={onDataSourceChange}
widgetId={props.id}
/>
After selecting a data source, you may want to allow the user to select fields from the data. To do this, you can use the FieldSelector component.
Like the data source, you should save the selected fields in app
as well.
{
props.useDataSources && props.useDataSources.length > 0 &&
<FieldSelector
useDataSources={props.useDataSources}
onChange={onFieldChange}
selectedFields={props.useDataSources[0].fields || Immutable([])}
/>
}
Read and display the data in the widget runtime
After a data source is selected in the widget settings, the widget runtime can get the selected data sources through props.use
. To read the data, use the Data
instance. To get the Data
instance, use Data
or Data
. To use Data
, pass the use
prop. To get the Data
instance, use the o
callback.
To read data, use the render function to display the data. See this sample widget. As an alternative, you can use the o
callback and update your widget UI in this callback function according to the current data in the data source.
If your widget must load data, pass in the query
and widget
props. The widget
is required because the framework uses this prop to manage the query parameters that multiple widgets apply to the same data source.
If you want to load data but do not want to change the data in the data source, pass in the local
prop. This will create a local data source for use. The recommended localId pattern is: widget
, for example widget_
.
When you render the Data
, the data source instance will be created but the data is not loaded initially because it's expecting you to pass in a query
prop which would cause another network request. To get the loaded data, you can use data
.
The data is paged and the default paging size is 100. The user can change the paging size in the builder data settings panel. The loaded data is cached on the client, and the cache will be cleared if the query criteria is changed.
When displaying the data, the displayed page size does not need to be the same as the query page size. For example, if the query paging size is 100, you can use data
to get the first 10 records to display.
To get the total number of records, pass in the query
prop, then get the count through data
.
Whenever the data source info is changed, the data render function and the o
callback will be invoked. The info includes the following:
instance
: whether the data source instance is created successfullyStatus status
: whether the data is loading or loadedcount
: whether the count of data is loading or loadedStatus selected
: the selected data IDsIds widget
: the query (filter) widgets applied to the data sourceQueries version
: the version number is used to manage the data change in the client side. Therefore, the data source consumers are aware when data is changed.gdb
: for feature services that support branch versioning. When the Branch Version Management widget switches the branch version, the version is saved here.Version
In many cases, the widget will need to compare the current data source info with the previous info to determine what needs to be updated.
If your widget needs to listen to the data source info change, but does not need to use the data records in the data source, you can omit the query
param and use the o
callback to do the query.
To get the fields in the data source, you can use data
.
Filter or query data based on user input
When a widget filters the data, the data in the data source instance is changed and all widgets will observe the change. When a widget queries data through a data source, the data in data source instance is not affected.
When multiple widgets apply a filter to the same data source, the attribute filters are tied together with and
operator(s). For geometry filters, the filter from the last widget (ordered by widget add order in the app config) to apply a geometry filter is used.
-
To filter a data source, there are two basic ways, depending on how the data source is configured:
- If the widget loads data, the recommended way is to use the
Data
like:Source Component
Use dark colors for code blocks Copy <DataSourceComponent useDataSource={} widgetId={} query={}> { Your render method } </DataSourceComponent>
You can find an example of using the
Data
in the Message subscriber sample and the Server-side output data source sample.Source Component Note: you can use
data
to load and filter the data as well.Source.load() - If the widget does not load data, you can use the
update
function of aQuery Params() Data Source
. See the Filter feature layer sample for an example.
- If the widget loads data, the recommended way is to use the
-
To query data through a data source, you can use
data
. When querying data, the filters applied to this data source are used as well.Source.query()
Handle selection on data
The designed selection behavior in an Experience Builder app is that all widgets should update and observe the same selection. For example, when a user selects a record within a List widget, the Text widget should see the selection if it uses the selection view. Every data source has a selection data view that manages the selection. Besides the selection data view, the selected record ID is saved in the Redux app store so widgets that use the data source can get notified when the selection is changed.
To select data records in a data source, you can use data
or data
.
If the records have been loaded in the data source, you don't need to pass in the second parameter. If not, you need to pass in the second parameter to make sure other widgets that use the selections can read the records.
To read the selection, you can use data
.
Use WebMap/WebScene
WebMap and WebScene from the ArcGIS Maps SDK for JavaScript are wrapped as data sources in the jimu-arcgis
package. To access a WebMap, use Web
; to access a WebScene, use Web
. Review the MapView sample to learn how to use these data sources. In addition to the WebMap and WebScene objects, all the layers in these objects are wrapped as data sources as well, which allows you to call get
to get all the layer data sources. The supported layers and services are defined by Supported
and Supported
.
Use FeatureLayer
In some workflows, you will be required to create a lightweight Experience that works with feature layers directly. In this scenario, you will use the Feature
classes. In general, a widget using a standalone feature layer will get a Feature
object without the layer
property, however using a feature layer from a webmap or webscene will return a Feature
object with the layer
property. The Layer
object is from the ArcGIS Maps SDK for JavaScript.
const getLayerObject = (ds: FeatureLayerDataSource) => {
return ds.layer; // this can be null
}
Sharing data between widgets
Widgets will often share the same data. A good illustration of this is using a Map and List widget in an experience. When a feature is selected in the List widget, the corresponding feature is selected on the map. The easiest way to accomplish this is to use the same data source for both widgets. For example, when an item is selected in the List widget, the widget will call datasource.select
to update the data source status in the app store.
This allows the Map widget to render the currently selected item accordingly. In addition, the currently selected item ID will be placed in the URL, which enables you to share the current app state with others.
Sync the data source with the ArcGIS Maps SDK for JavaScript feature object
In an Experience Builder widget you can use the ArcGIS Maps SDK for JavaScript to get features. Then you may want to allow other widgets to use those features. For example, you may need to highlight these features on map, or show these features in List widget. You have 3 options to do this, listed below.
- Select these feature records in a data source
- If there is a data source instance you can use, you can just call
data
to select these records. If what you get is aSource.select Records By Ids() Graphic
instance, you need to create aFeature
instance first.Record
- If there is a data source instance you can use, you can just call
- Generate an output data source from your widget
- See the Widget output data source sample.
- Publish a message
- If your widget generates some features, you can publish the
Data
message so other widgets can subscribe.Record S e t Change Message
- If your widget generates some features, you can publish the
Work with MapView/SceneView or LayerView
In many cases, when your widget works with a data source, it may need to work with MapView/SceneView as well. After the widget gets a Jimu
instance through Jimu
, you can get the corresponding data source of the MapView/SceneView by jimu
, and you can get the related layers through jimu
. Through the Jimu
instance, you can get the corresponding data source of the layer view by jimu
as well. Generally, to get a feature from a layer to sync with a data source, you have these options:
- Use the
object
of the feature to find the related data records in the data sourceI d - Create a data record through the feature by creating a
Feature
instanceData Record - From a
Feature
instance, you can get the feature by usingData Record feature
Data Record.get Feature()