I'm writing a custom widget in Experience Builder 1.5. In a fist step I render html content from a feature layer. After the feature has loaded im loading a related table. After this table has load I'd like to call the render function again and update the content. Unfortunately the content will no be altered. How can I change my content on later point of time? That's seems the question. My actual code looks like this:
import { getFeatureLayerFromDataSource } from 'dist/widgets/arcgis/query/src/runtime/widget-utils';
import { React, IMDataSourceInfo, DataSource, DataSourceManager, DataSourceStatus, FeatureLayerQueryParams, AllWidgetProps, DataSourceComponent, FeatureServiceDataSource } from 'jimu-core';
import { Card, CardHeader, CardBody, CardFooter } from 'jimu-ui';
import { MapViewManager, JimuMapView, JimuMapViewComponent, JimuFeatureLayerView } from "jimu-arcgis";
import * as FeatureLayerView from 'esri/views/layers/FeatureLayerView';
import * as FeatureSet from 'esri/tasks/support/FeatureSet';
interface IState {
query: FeatureLayerQueryParams;
jimuMapView: JimuMapView;
relatedDataLoaded: Boolean;
el: React.ReactElement;
}
/**
* This widget will show features from a configured feature layer
*/
export default class Widget extends React.PureComponent<AllWidgetProps<{}>, IState>{
state = {
query: {},
jimuMapView: null,
relatedDataLoaded: false,
el: <div>Text</div>
};
query = () => {
if (!this.isDsConfigured()) {
return;
}
this.setState({
query: {
where: '"EpId <> 0"',
outFields: ['*'],
pageSize: 10
}
});
}
isDsConfigured = () => {
if (this.props.useDataSources &&
this.props.useDataSources.length > 0)
{
return true;
}
return false;
}
dataRender2() {
return this.state.el
}
dataRender = (ds: DataSource, info: IMDataSourceInfo) => {
var that = this;
if (ds && ds.getStatus() === DataSourceStatus.Loaded && this.state.jimuMapView) {
var view: JimuFeatureLayerView = this.state.jimuMapView.jimuLayerViews["widget_1-dataSource_1-EPIS_Projekt_Ideen_3405"];
var featureLayer = view.layer;
const query = {
outFields: ["*"],
relationshipId: 1,
objectIds: [1, 2]
}
featureLayer.queryRelatedFeatures(query).then(function (result) {
this.setState({ relatedDataLoaded: true })
this.OverviewCard(featureSet.features[0].attributes)
// // })
// test
// }
// </div>
this.state.el = <div>New Text</div>
this.render()
}.bind(this)).catch(function (error) {
console.log("error from queryRelatedFeatures", error);
});
}
if (this.state.jimuMapView) {
}
return <>
<div>Query state: {info.status}</div>
<div>Count: {ds.count}</div>
<div className="record-list" style={{ width: '100%', marginTop: '20px', height: 'calc(100% - 80px)', overflow: 'auto' }}>
{
ds && ds.getStatus() === DataSourceStatus.Loaded && this.state.jimuMapView ? ds.getRecords().map((r, i) => {
var fds: FeatureServiceDataSource = ds as FeatureServiceDataSource;
//var test = getFeatureLayerFromDataSource(ds,null,this.props.id);
//return this.OverviewCard(r)
//return <div key={i}>{r.getData()["EpID"]}</div>
}) : null
}
</div>
</>
}
render() {
if (!this.isDsConfigured()) {
return <h3>
Folgende Datenquellen müssen konfiguriert werden:
<br />
- Feature Class Massnahmen
</h3>;
}
let dsm = DataSourceManager.getInstance();
dsm.createAllDataSources().then(value => {
});
if (this.state.relatedDataLoaded) {
return this.state.el
}
return <div className="widget-use-feature-layer" style={{ width: '100%', height: '100%', maxHeight: '800px', overflow: 'auto' }}>
<h3>
Projekte und Projektideen.
</h3>
{this.props.hasOwnProperty("useMapWidgetIds") &&
this.props.useMapWidgetIds &&
this.props.useMapWidgetIds.length === 1 && (
<JimuMapViewComponent
useMapWidgetId={this.props.useMapWidgetIds?.[0]}
onActiveViewChange={(jmv: JimuMapView) => {
this.setState({
jimuMapView: jmv,
});
}}
/>
)}
<DataSourceComponent useDataSource={this.props.useDataSources[0]} query={{}} widgetId={this.props.id} queryCount>
{
this.dataRender
}
</DataSourceComponent>
</div>;
}
OverviewCard(feature) {
return <Card active>
<CardHeader>
<h5>
{feature["EpID"]}
</h5>
</CardHeader>
<CardBody>
<h5>
Card content
</h5>
<p>
Example text for the card content.
</p>
</CardBody>
<CardFooter>
Card Footer
</CardFooter>
</Card>
}
}
After I call this.render() on line 74 the function will be executed and return the new value "new text" but the widget show still the old value "test". How can I pass new content to the widget after first rendering?