I have inherited a custom widget that grabs a csv from a dynamic location, creates a JSAPI CSVLayer and adds it to the map. This is working without issue in ExB 1.13.
I need to integrate this layer with the attribute table widget.
I've seen a few posts suggesting that the way to accomplish this is to create an output datasource for the widget in the settings page.
I've done this using the following code:
const outputDsJsons: DataSourceJson[] = [{
id: `${props.id}-output`,
type: DataSourceTypes.FeatureLayer,
label: "Test Layer",
originDataSources: [],
schema: {
idField: "objectid",
fields: {
objectid: {
jimuName: "objectid",
name: "objectid",
alias: "OBJECTID",
type: JimuFieldType.Number,
esriType: EsriFieldType.OID
},
state: {
jimuName: "Route",
name: "Route",
alias: "Route",
type: JimuFieldType.Number,
esriType: EsriFieldType.Integer
},
clicks: {
jimuName: "Bus",
name: "Bus",
alias: "Bus",
type: JimuFieldType.Number,
esriType: EsriFieldType.Integer
}
}
},
isDataInDataSourceInstance: true
}]
this.props.onSettingChange({
id: props.id,
useDataSources: []
}, outputDsJsons);
I can see this output in the settings page of other widgets. So, for example, I can add it as a "New sheet" to the Attribute Table widget and the configured schema looks correct.
However, I can't figure out how to access this datasource and update it's records at run time. I can get a reference to the DataSourceManager and see all of the other datasources in the app but my custom output datasource doesn't appear.
I'm not sure what I'm missing or where to go from here.
Any insight is greatly appreciated.
Jill
Solved! Go to Solution.
I finally got this working and am leaving my solution here in case it helps someone else.
I added the following to the constructor of the settings page of my custom widget.
const outputDsJsons: DataSourceJson[] = [{
id: `${props.id}-output`,
type: DataSourceTypes.FeatureLayer,
label: "QlikView Layer",
originDataSources: [],
schema: {
idField: "__OBJECTID",
fields: {
__OBJECTID: {
jimuName: "__OBJECTID",
name: "__OBJECTID",
alias: "__OBJECTID",
type: JimuFieldType.Number,
esriType: EsriFieldType.OID
},
Route: {
jimuName: "Route",
name: "Route",
alias: "Route",
type: JimuFieldType.Number,
esriType: EsriFieldType.Integer
},
.....
}
},
isDataInDataSourceInstance: true
}]
this.props.onSettingChange({
id: this.props.id,
useDataSources: []
}, outputDsJsons);
Then I added the output datasource as a new sheet in my attribute table widget.
In my widget source I used the following to populate the records:
const dataRecords = [];
const dataSourceManager = DataSourceManager.getInstance();
const outputDsId = this.props.outputDataSources[0]
dataSourceManager.createDataSource(outputDsId).then(ods => {
csvLayer.queryFeatures().then((results) => {
results.features.forEach((f) => {
const rec = ods.buildRecord(f)
dataRecords.push(rec);
});
ods.setSourceRecords(dataRecords)
ods.setStatus(DataSourceStatus.Unloaded)
ods.setCountStatus(DataSourceStatus.Unloaded)
})
});
No idea if this is the proper way to do this. I found it incredibly frustrating trying to implement this with the available documentation. I managed to piece something together from samples and community posts.
Jill
I finally got this working and am leaving my solution here in case it helps someone else.
I added the following to the constructor of the settings page of my custom widget.
const outputDsJsons: DataSourceJson[] = [{
id: `${props.id}-output`,
type: DataSourceTypes.FeatureLayer,
label: "QlikView Layer",
originDataSources: [],
schema: {
idField: "__OBJECTID",
fields: {
__OBJECTID: {
jimuName: "__OBJECTID",
name: "__OBJECTID",
alias: "__OBJECTID",
type: JimuFieldType.Number,
esriType: EsriFieldType.OID
},
Route: {
jimuName: "Route",
name: "Route",
alias: "Route",
type: JimuFieldType.Number,
esriType: EsriFieldType.Integer
},
.....
}
},
isDataInDataSourceInstance: true
}]
this.props.onSettingChange({
id: this.props.id,
useDataSources: []
}, outputDsJsons);
Then I added the output datasource as a new sheet in my attribute table widget.
In my widget source I used the following to populate the records:
const dataRecords = [];
const dataSourceManager = DataSourceManager.getInstance();
const outputDsId = this.props.outputDataSources[0]
dataSourceManager.createDataSource(outputDsId).then(ods => {
csvLayer.queryFeatures().then((results) => {
results.features.forEach((f) => {
const rec = ods.buildRecord(f)
dataRecords.push(rec);
});
ods.setSourceRecords(dataRecords)
ods.setStatus(DataSourceStatus.Unloaded)
ods.setCountStatus(DataSourceStatus.Unloaded)
})
});
No idea if this is the proper way to do this. I found it incredibly frustrating trying to implement this with the available documentation. I managed to piece something together from samples and community posts.
Jill
This is great Jillian you should add this to the custom widgets group, can't wait to test this out https://community.esri.com/t5/experience-builder-custom-widgets/gh-p/eb-custom-widgets