Select to view content in your preferred language

Custom Widget Output Datasource

1219
2
Jump to solution
02-01-2024 02:18 PM
Labels (1)
JillianStanford
Frequent Contributor

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.

JillianStanford_0-1706825296383.png

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.

JillianStanford_1-1706825520596.png

I'm not sure what I'm missing or where to go from here.

Any insight is greatly appreciated.

Jill

1 Solution

Accepted Solutions
JillianStanford
Frequent Contributor

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.

JillianStanford_0-1707860972044.png

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

 

 

 

 

 

 

View solution in original post

2 Replies
JillianStanford
Frequent Contributor

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.

JillianStanford_0-1707860972044.png

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

 

 

 

 

 

 

WDominguez-Zarate
Emerging Contributor

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 

0 Kudos