Select to view content in your preferred language

Loss of renderer with runtime-created data source

345
9
Jump to solution
3 weeks ago
jwilner_amica
Occasional Contributor

Following this post, I created a DataSource from a programmatically generated FeatureLayer.

https://community.esri.com/t5/arcgis-experience-builder-questions/making-runtime-featurelayers-regis...

However, when that DataSource is added to map, it loses its renderer that was defined before. The renderer being used displays some color never used in my UniqueValueRenderer. The code is as follows:

                let layer = new FeatureLayer({
                  source: featureset,  // autocast as a Collection of new Graphic()
                  objectIdField: "OBJECTID",
                  geometryType: "polygon",
                  popupTemplate: template,
                  fields: swath.value.fields,
                  title: 'Hail Swath ' + dt,
                  opacity: 0.8
                })
                layer.renderer = {
                  type: "unique-value",  // autocasts as new UniqueValueRenderer()
                  // @ts-ignore
                  field: "diameter_in_label",
                  defaultSymbol: {
                    type: "simple-fill",
                    outline: line,
                    color: [209, 0, 152, 1.0]
                  },
                  uniqueValueInfos: [{
                    value: '0.75"',
                    symbol: {
                      type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                      color: [255, 255, 190, 1.0],
                      outline: line
                    }
                  }, ... ** Omitted long renderer **
                  }]
                }
 
                const data: DataSourceJson = {
                  id: 'Hail Swath ' + dt,
                  layerId: layer.id,
                  type: DataSourceTypes.FeatureLayer,
                  label: layer.title,
                }

                const dataJson = Immutable(data)
                const dataSourceOptions = {
                  id: 'Hail Swath ' + dt,
                  layer: layer,
                  dataSourceJson: dataJson,
                }

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

                  let mapDatas = { sourceId: addMapData }
                  map.current.addOrRemoveDataOnMap(mapDatas)
 
                }).catch((error) => {
                  console.error('Error creating DataSource:', error);
                });
 
Any help would be appreciated, thank you!
0 Kudos
2 Solutions

Accepted Solutions
jwilner_amica
Occasional Contributor

Got a functional result. Rather than adding DataSource to map, add the FeatureLayer, then add that FeatureLayer to a JimuLayerView, specifying creation during runtime ('true' flag in constructor). Use the DataSource id created earlier in the JimuLayerView constructor as well. Symbology transfers and has datasource functionality:

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

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

                }).catch((error) => {
                  console.error('Error creating DataSource:', error);
                });
 
ExB 1.15 Bug:
Layer loses DataSource functionality upon reorder
 

View solution in original post

YueyangLi
Esri Contributor

Hi @jwilner_amica,

The addOrRemoveDataOnMap method should be private. It creates a graphic layer based on the records from the data source, which explains why the renderer isn't functioning properly. We will update the code accordingly.

If you'd prefer to create the data source first and then add it to the map, you can use jimuMapView.addLayerToMap(dsId, customLayerId).
 
I hope this helps.

View solution in original post

9 Replies
jwilner_amica
Occasional Contributor

When logging my DataSourceManager (dsManager) immediately after the 'addOrRemoveDataOnMap(mapDatas)' line, I get the renderer displayed as such:

jwilner_amica_0-1726667366770.png

So it does seem to be there, but not taking any effect.

0 Kudos
JeffreyThompson2
MVP Regular Contributor

I think that because your render is not defined within the DataSourceJson, it is triggering the layer to load with the default renderer. Try moving the layer.renderer = {...} below adding it to the map, so it will first load with the default renderer and then get the unique values.

GIS Developer
City of Arlington, Texas
0 Kudos
jwilner_amica
Occasional Contributor

Unfortunately, 

map.current.addOrRemoveDataOnMap(mapDatas)

layer.renderer = {**Omitted renderer**}

did not seem to solve the issue. I also tried putting both lines into a timeout, as you did in the original post, as well as putting the layer.renderer overwrite alone into a timeout, to ensure that the update occurred after the add to map, but neither seemed to have any effect. Is there a way to specify the renderer directly in the DataSourceJson? I couldn't seem to find one, but it is possible I overlooked something. Thank you for your help, you have quite a wealth of knowledge with the ExB developer system!

0 Kudos
JeffreyThompson2
MVP Regular Contributor

I am currently working on an update to my add/remove layers widget that will register the layers as datasources. I should have it out later today.

https://community.esri.com/t5/experience-builder-custom-widgets/add-remove-layers-by-group/m-p/12950...

While working on the problem linked to in your original question, I found an issue in that code that adding the datasource causes an additional datasource enabled layer to be added to the map and there were issues with conflicting ids. I think your code could have a similar problem. My widget works by adding the layer (not as a datasource) to the map, using that layer to make a datasource with a different id and then deleting the original layer. 

GIS Developer
City of Arlington, Texas
0 Kudos
jwilner_amica
Occasional Contributor

I will look through that, thank you!

0 Kudos
jwilner_amica
Occasional Contributor

@JeffreyThompson2 Got a functional datasource add, may make your widget a bit cleaner than add-remove, but could still use some testing. Hope this can help!

0 Kudos
jwilner_amica
Occasional Contributor
 
0 Kudos
jwilner_amica
Occasional Contributor

Got a functional result. Rather than adding DataSource to map, add the FeatureLayer, then add that FeatureLayer to a JimuLayerView, specifying creation during runtime ('true' flag in constructor). Use the DataSource id created earlier in the JimuLayerView constructor as well. Symbology transfers and has datasource functionality:

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

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

                }).catch((error) => {
                  console.error('Error creating DataSource:', error);
                });
 
ExB 1.15 Bug:
Layer loses DataSource functionality upon reorder
 
YueyangLi
Esri Contributor

Hi @jwilner_amica,

The addOrRemoveDataOnMap method should be private. It creates a graphic layer based on the records from the data source, which explains why the renderer isn't functioning properly. We will update the code accordingly.

If you'd prefer to create the data source first and then add it to the map, you can use jimuMapView.addLayerToMap(dsId, customLayerId).
 
I hope this helps.