how to view/add client side feature layer into table widget ?

443
12
Jump to solution
12-16-2024 04:17 AM
mohannainar1
Occasional Contributor

I created new feature layer from client side and added into map in experience builder developer edition.

Now I want to see the layer in table widget. 

In web app builder, once we add the layer programmatically the attribute information will be displayed automatically. Not sure how to implement in experience builder

 

 

  const activeViewChangeHandler = (jmv: JimuMapView) => {
    if (jmv) {
      setJimuMapView(jmv)
      jmv.view.when(() => {
        console.log("Map loaded");
        setIsMapLoaded(true);
        setLoading(false);  
        // Add sample graphic
        const ptGraphic = new Graphic({
          geometry: {
            type: "point",
            longitude: -118.805,
            latitude: 34.027
          },
          attributes: {
            Name: "Sample Point",
            Description: "This is a sample description"
          }
        });
        const layer = new FeatureLayer({
          source: [ptGraphic],
          fields: [{
            name: "ObjectID",
            alias: "ObjectID",
            type: "oid"
          }, {
            name: "place",
            alias: "Place",
            type: "string"
          },{
            name: "Description",
            alias: "Description",
            type: "string"
          }],
          objectIdField: "ObjectID",
          geometryType: "point"
        });
        layer.title = "Sample Layer";
        jmv.view.map.add(layer);
0 Kudos
1 Solution

Accepted Solutions
JeffreyThompson2
MVP Regular Contributor

I just started making a 1.16 compatible datasource today. It looks like this block of code will make a datasource from a FeatureLayer and add it to a map. I think it should work in 1.14 and 1.16, but I have not tested in 1.14.

Edit: Tested. This code does not work in 1.14. The addLayerAndCreateJimuLayerView() method is not available.

 

const fetchDataSourceJson = async (dsId: string, layer: object) : Promise<IMDataSourceJson> => {
	const dsJson = await dataSourceJsonCreator.createDataSourceJsonByJSAPILayer(dsId, layer)
	console.log(dsJson)
	return dsJson
}

const createDataSource = async (dsId: string, layer: object) : Promise<DataSource> => {
	const dsJson = await fetchDataSourceJson(dsId, layer)
	const dsOptions: FeatureLayerDataSourceConstructorOptions = {
		id: dsId,
		dataSourceJson: dsJson
	}
	console.log(dsOptions)
	return DataSourceManager.getInstance().createDataSource(dsOptions)
}

const makeLayerView = async layer => {
	const dataSource = await createDataSource(layer.id, layer)
	const layerView = await jimuMapView.addLayerAndCreateJimuLayerView(layer, dataSource)
	console.log(layerView)
}

//call function
makeLayerView(featureLayer)

 

 

GIS Developer
City of Arlington, Texas

View solution in original post

12 Replies
JeffreyThompson2
MVP Regular Contributor

You will first need to convert your layer to a datasource and then register it with the framework. The method I have used for framework registration has been removed in Developer Edition 1.16, so I do not currently have the complete code for the process. Take a look at these two posts and you should be able to stitch together the complete answer.

https://community.esri.com/t5/arcgis-experience-builder-questions/loss-of-renderer-with-runtime-crea...

https://community.esri.com/t5/arcgis-experience-builder-questions/confusion-in-how-to-manage-data-so...

GIS Developer
City of Arlington, Texas
mohannainar1
Occasional Contributor

I refered the first link as suggested by you and it worked in Developer edition 1.16. The same logic I tried in 1.14 it did not work and not throwing any error message. The reason I am using 1.14 is my Portal version is 11.3. 

 

const layer = new FeatureLayer({
          source: [ptGraphic],
          fields: [{
            name: "ObjectID",
            alias: "ObjectID",
            type: "oid"
          }, {
            name: "place",
            alias: "Place",
            type: "string"
          },{
            name: "Description",
            alias: "Description",
            type: "string"
          }],
          objectIdField: "ObjectID",
          geometryType: "point"
        });
        layer.title = "Sample Layer";
        layer.id = "sampleLayer";

 

       

        const dataSourceManager = DataSourceManager.getInstance();
        const dataSourceId = "dataSource_1";

        //const layerInfo = jmv.view.map.allLayers.items[39]

       
        //const dataSourceId = "dataSource_1";

        const data: DataSourceJson = {
          id: 'sample layer',
          layerId: layer.id,
          type: DataSourceTypes.FeatureLayer,
          label: layer.title,
        }

        const dataJson = Immutable(data)
        const dataSourceOptions = {
          id: 'Sample client side layer',
          layer: layer,
          dataSourceJson: dataJson,
        }

        //const jimuLayerView = await jimuMapView.addLayerAndCreateJimuLayerView(layer, dataSource);

        dataSourceManager.createDataSource(dataSourceOptions).then((source) => {
          const sourceId = source.id
          const addMapData = {
            jimuMapViewId: jmv.id,
            dataSourceId: sourceId,
            dataChangeType: DataChangeType.Create,
            dataChangeStatus: DataChangeStatus.Fulfilled            
          }

          jmv.view.map.add(layer)
          jmv.createJimuLayerView(layer, jmv.id, 0, source, true)

          //let mapDatas = { sourceId: addMapData }
          //jmv.view.map.addOrRemoveDataOnMap(mapDatas)

        }).catch((error) => {
          console.error('Error creating DataSource:', error);
        });
     
 
0 Kudos
JeffreyThompson2
MVP Regular Contributor

I just started making a 1.16 compatible datasource today. It looks like this block of code will make a datasource from a FeatureLayer and add it to a map. I think it should work in 1.14 and 1.16, but I have not tested in 1.14.

Edit: Tested. This code does not work in 1.14. The addLayerAndCreateJimuLayerView() method is not available.

 

const fetchDataSourceJson = async (dsId: string, layer: object) : Promise<IMDataSourceJson> => {
	const dsJson = await dataSourceJsonCreator.createDataSourceJsonByJSAPILayer(dsId, layer)
	console.log(dsJson)
	return dsJson
}

const createDataSource = async (dsId: string, layer: object) : Promise<DataSource> => {
	const dsJson = await fetchDataSourceJson(dsId, layer)
	const dsOptions: FeatureLayerDataSourceConstructorOptions = {
		id: dsId,
		dataSourceJson: dsJson
	}
	console.log(dsOptions)
	return DataSourceManager.getInstance().createDataSource(dsOptions)
}

const makeLayerView = async layer => {
	const dataSource = await createDataSource(layer.id, layer)
	const layerView = await jimuMapView.addLayerAndCreateJimuLayerView(layer, dataSource)
	console.log(layerView)
}

//call function
makeLayerView(featureLayer)

 

 

GIS Developer
City of Arlington, Texas
ericsamson_tract
Regular Contributor

hey Jeff, do you mind including your imports? I can't for the life of me figure out where to import dataSourceJsonCreator or FeatureLayerDataSourceConstructorOptions from. I tried jimu-core and jimu-arcgis and a few other things, just can't get it working. Thanks!

0 Kudos
JeffreyThompson2
MVP Regular Contributor
import { React, AllWidgetProps, DataSourceManager, type IMDataSourceJson, type DataSource } from 'jimu-core'
import { JimuMapViewComponent, JimuMapView, MapViewManager } from 'jimu-arcgis'
import { dataSourceJsonCreator, type FeatureLayerDataSourceConstructorOptions } from 'jimu-core/data-source'

They created a 'jimu-core/data-source' module with the 1.16 release.

GIS Developer
City of Arlington, Texas
0 Kudos
KenBuja
MVP Esteemed Contributor

@JeffreyThompson2Where is this documented?

0 Kudos
JeffreyThompson2
MVP Regular Contributor

https://github.com/Esri/arcgis-experience-builder-sdk-resources/tree/master/widgets/data-source-widg...

I think this sample widget is as close as we are getting to actual documentation.

GIS Developer
City of Arlington, Texas
0 Kudos
ericsamson_tract
Regular Contributor

Thanks Jeff for all the information! I am however still getting stuck...I am attempting to transform a geojson to a featurelayer and then have that featurelayer be a data source that we can then add to the attribute table. I am able to transform and add to the map fine, and the code you offered above also allows me to click the "add to table" option within the layerlist. However, when I click that I get an error that there is no item id:

No item id. data-source.js:1
Uncaught (in promise) TypeError: Cannot convert undefined or null to object add-to-table.js:1

Here's my relevant code section:

 

const layer = createFeatureLayerFromGeoJSON({
      geojson: geojsonData,
      title: "Parcels",
      wkid: 4326,
      geometryType: 'polygon'
    });

    //jimuMapView.view.map.add(layer);

    const fetchDataSourceJson = async (dsId: string, layer) : Promise<IMDataSourceJson> => {
      const dsJson = await dataSourceJsonCreator.createDataSourceJsonByJSAPILayer(dsId, layer)
      console.log(dsJson)
      return dsJson
    }
    
    const createDataSource = async (dsId, layer) : Promise<DataSource> => {
      const dsJson = await fetchDataSourceJson(dsId, layer)
      const dsOptions: FeatureLayerDataSourceConstructorOptions = {
        id: dsId,
        dataSourceJson: dsJson
      }
      console.log(dsOptions)
      return DataSourceManager.getInstance().createDataSource(dsOptions)
    }
    
    const makeLayerView = async layer => {
      const dataSource = await createDataSource(layer.id, layer)
      const layerView = await jimuMapView.addLayerAndCreateJimuLayerView(layer, dataSource)
      console.log(layerView)
    }

    makeLayerView(layer)

 

 

I am also getting a curious typescript error on the id line within the createdatasource function:
"Object literal may only specify known properties, and 'id' does not exist in type 'FeatureLayerDataSourceConstructorOptions'.ts(2353)"
Which doesn't make sense to me since I am using the same code that ESRI has in their example.

Any leads would be much appreciated. 

0 Kudos
JeffreyThompson2
MVP Regular Contributor

Where is the createFeatureLayerFromGeoJSON() function coming from? I'm not familiar with it.

The issue I see is that you are using layer.id in the createDataSource() function, but the layer object in the createFeatureLayerFromGeoJSON() does not have an id property. Is it created by this function?

GIS Developer
City of Arlington, Texas
0 Kudos