Select to view content in your preferred language

Dynamic fields on feature layer with client-side graphics

452
0
11-28-2022 11:19 AM
PrecisionAnalytics
New Contributor

Hello Esri Community,

I’m currently running into a problem with updating dynamic fields on a feature layer so that our dynamic client-side graphics have the attributes/data they need to be styled by our active legend. We are using React, arcgis/core (4.22), and consuming data from a java rest api. We currently have this setup to use graphic layers, which works great, but would like to harness some more capabilities that ESRI has to offer by using feature layers. I can see the fields on the layer but they are not attached to the graphics sometimes - I initially thought this was a race condition but have tried many different sequences to no avail.

Attached are some screenshots (sensitive info redacted) of the 3 scenarios - 

  1. Initial render that works
  2. Initial render that doesn't work
  3. Initial render then changing graphics with applyEdits (doesn't work)

 

  const assetMarkersLayer = useRef<__esri.FeatureLayer>(
    new FeatureLayer({
      source: [],
      title: 'test2',
      minScale: ASSET_MARKER_SCALE_MIN,
      objectIdField: 'oid',
      // featureReduction: {
      //   type: 'cluster',
      //   clusterRadius: 20,
      // },
      geometryType: 'point',
      labelingInfo: [
        {
          symbol: {
            type: 'text',
          },
          labelPlacement: 'below-center',
          labelExpressionInfo: {
            expression: '$feature.sequenceNumber',
          },
        },
      ],
      fields: [],
      outFields: ['*'],
      renderer: {
        type: 'unique-value',
        defaultSymbol: {
          type: 'simple-marker',
          size: 16,
          color: '#efefef',
        },
      },
    })
  )

  useEffect(() => {
    const fields = [
      { name: 'uuid', type: 'string' },
      { name: 'sequenceNumber', type: 'integer' },
      { name: 'currentStatus', type: 'string' },

      ...Object.keys(allAssetLegends).map(name => ({
        name,
        type: 'string',
      })),
    ]
    assetMarkersLayer.current.set({ fields })
  }, [allAssetLegends])

  useEffect(() => {
    if (!activeAssetLegend.values) return

    assetMarkersLayer.current.renderer.set({
      field: activeAssetLegend.id,
      uniqueValueInfos: activeAssetLegend.values.map(({ id, color }) => ({
        value: id,
        symbol: { type: 'simple-marker', size: 16, color },
      })),
    })
  }, [activeAssetLegend])

  const prevAssets = useRef<__esri.Collection[]>([])
  useEffect(() => {
    const assets = allMapAssets.map(asset => getAssetMarker(asset))

    void assetMarkersLayer.current
      .applyEdits({
        deleteFeatures: prevAssets.current,
        addFeatures: assets,
      })
      .then((results: { addFeatureResults: __esri.Collection[] }) => {
        prevAssets.current = results.addFeatureResults

        return results
      })
  }, [allMapAssets])

 

 
Thank you for your time and any advice!

0 Kudos
0 Replies