Select to view content in your preferred language

How to update / add feature attributes?

777
5
11-16-2022 01:31 PM
AndrewMurdoch1
Frequent Contributor

Good Day

I already know about setAttribute, my question is how save the update so my attribute become available?

 

this.grabData().then(() => {
	this.queryAllFeatures(this._layers[0]).then((features: Graphic[]) => {
  		features.forEach((feature, idx) => {
    			const matchedFeature = this.data.find(d => d.x === feature.attributes.x)
	
    			if (matchedFeature) {
			      const value1 =
				matchedFeature?.box?.find(i => i.type === 'a').value ?? 0;

				feature.setAttribute('someValue', Number(value1));
				// Repeated X times
    			}
  		})
  	})
})

 


If I do this, and try to reference "someValue" I get an error that it doesn't exist, so I tried to use "applyEdits" to update the value:

 

this._layers[0].applyEdits({ updateFeatures: features })
    .then((editsResult) => {
        console.log('Edit Results');
        console.log(editsResult);
    })
    .catch((error) => {
        console.log("error = ", error);
});

 



Which works, but I still don't see my new attributes.  Previous I was getting an error from applyEdits, but I resolved that problem! 

Can anyone see what I'm doing wrong? 

Thanks

0 Kudos
5 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

It is hard to suggest anything without a repro case. Are you working with a FeatureLayer that references a feature service or is this a client-side FeatureLayer? You should see the updated values for feature services without having to do anything as long as applyEdits resolves successfully. For client-side featureLayer, you have to query the updated features once applyEdits resolves successfully. 

It is explained in this document: https://next.sites.afd.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#appl...

This very simple sample shows and explains this workflow: https://developers.arcgis.com/javascript/latest/sample-code/layers-featurelayer-collection-edits/

 

AndrewMurdoch1
Frequent Contributor

Good Day

Thanks for the reply, I'm using a Hosted Feature Layer, please see this more complete example:

addGISFeatureAttributes(layer: FeatureLayer) {
    return new Promise((r) => {
      console.time('correlationLook10k');
      this.queryAllFeatures(layer).then((features: Graphic[]) => {
        this.grabData().then(() => {
          features.forEach((feature, idx) => {
            const matchedFeature =
              this.data.find(d => d.x === feature.attributes.x)

            if (matchedFeature) {
              const value1 =
                matchedFeature?.find(m => m.type === 'v1').value ?? 0;

              const value2 =
                matchedFeature?.find(m => m.type === 'v1').value ?? 0;
                
              const value3 =
                matchedFeature?.find(m => m.type === 'v1').value ?? 0;
                
              feature.setAttribute('v1', Number(value1));
              feature.setAttribute('v2', Number(value2));
              feature.setAttribute('v3', Number(value3));
              feature.attributes.v4 = Number(value3);
            }
          })

          layer.applyEdits({updateFeatures: features}).then((updateResults) => {
            console.log('Update Results');
            console.log(updateResults);

            const query = {
              where: '1=1',
              outFields:['*'],
              returnGeometry: true,
              maxRecordCountFactor: 5
            }

            const objectIds = [];
            updateResults.updateFeatureResults.forEach((item) => {
              objectIds.push(item.objectId);
            });

            console.log('Object Ids');
            console.log(objectIds);

            layer.queryFeatures(query).then((results) => {
              console.log(results.features.length, "features have been added.");
              console.timeEnd('correlationLook10k');
              r(results);
            }).catch((error) => {
              console.log('Query Feature Error');
              console.log(error);
            })
          }).catch((error) => {
            console.log('Upload Error');
            console.log(error);
          })
        });
      });
    });
  }

  showPortalFeatureLayerByYear(year: number = new Date().getFullYear()) {
    let layerId = "SOME PORTAL ID"

    this._layers = [];
    new FeatureLayer({
      portalItem: {
        id: layerId,
      },
      outFields: ['*']
    }).load().then((layer) => {
      this.addGISFeatureAttributes(layer).then((features: FeatureSet) => {

        console.log('Features');
        console.log(_.cloneDeep(features));

        return new FeatureLayer({
          source: features.features,
          fields: features.fields,
          renderer: null,
          spatialReference: {
            wkid: 102100
          },
          outFields: ["*"]
        }).load().then((layer) => {
          this._layers.push(layer);
          this.renderHostedFeatureLayer();
        })
      })
    })
  }

 

Should I have my new layer with v1 -> v4?  This does the applyEdits, and this does the query stage.  One thing I've noticed, this is slow, ~60 seconds for 10k assets, so this generally not recommended?

Thanks

0 Kudos
ReneRubalcava
Honored Contributor

Can you verify that the fields you are trying to update are in the the layers fields array?

0 Kudos
AndrewMurdoch1
Frequent Contributor

Yes, they exist, the features all contain v1 -> v4, v1 is always a number from 0 - 100 in string form, and I'm doing feature.setAttribute('v1', "SUPERRANDOMSET").  After that logic runs v1 is still "0" - "100", when I expect it to be "SUPERRANDOMSET".

Could there be a problem running the update on a layer that was created from ArcGIS Online? I've been able to do this with client side graphics when I build them manually.


0 Kudos
AndrewMurdoch1
Frequent Contributor

The other question I should ask, is this even recommended or practical to do?  We could have layers with 100k+ features in them, and we'd want to perform the same kind of step, is there anyway to do this at scale and with minimal latency?

0 Kudos