[GIS] Esri Javascript API .applyEdits() firing on(“edits-complete”), not erroring, but not updating the database

arcgis-javascript-api

This is a log of my troubleshooting chat in The Spatial Community Slack. I thought it could be helpful to memorialize it once the 10,000 message monster eats it.

I'm struggling to get featureLayer.applyEdits() working

It's hitting the callback, but not firing on('edits-complete')

it's silently doing nothing

after hitting submit, the data doesn't update

here's where it's called:
RRWCFeatureLayer.applyEdits(null, feature, null, clearForm, errback)

the feature object is a graphic returned by a queryTask, appended with attribute information typed into the page. It's currently a hosted feature service for dev. Eventually it'll point to a Server service.

davetimmins: the edits expects an array so try RRWCFeatureLayer.applyEdits(null, [feature], null, clearForm, errback)

changing it to [feature] allowed the on("edits-complete") to fire… but the data doesn't actually change in the database

so when I look at an example with .applyEdits() passes back an object that is similar but not identical to the object I'm using

From Esri’s attribute inspector example

esris examples

My object

my object

the docs just say it needs a valid objectid

i'm modifying the object returned by a QueryTask

does my object not contain the necessary properties to be a proper Graphic?

do I need to run feature.setAttributes() rather than just setting the properties directly using feature.attributes.<field> = "value"?

jmfolds: I ran into something similar to this recently. I feel like I ended up querying the featureLayer directly for the graphic. It seemed like the graphic passed to featureLayer.applyEdits to update had to exist in the featureLayer.graphics array or something? I could also be completely wrong.

oh and i just tested using setAttributes() and the layer still isn't updating. It replaces all the attributes with ones that I set.

davetimmins: use this graphic var graphic = new Graphic(results.features[0].geometry, symbol), set the attributes for that too and then pass that to the applyEdits

jmfolds: ah ddavetimmins I didn't notice that. themapsmith I think if you use feature = new Graphic(results.features[0].geometry, symbol, results.features[0].attributes) that should work?

That got my graphic down into my submit code but it’s still not updating the data.

Digging into the NCAA update example, i'm noticing some other subtle differences

the UpdateFeatures object being submitted has _count:2 and _cache: null properties, otherwise the top level properties are the same

When i look at the network request, my feature JSON looks like this:

    [
       {
          "geometry":{
             "x":-73.24948728213145,
             "y":44.181510999714426,
             "spatialReference":{
                "wkid":4326,
                "latestWkid":4326
             }
          },
          "attributes":{
             "OBJECTID":1300,
             "AppDate":1467345600000,
             "CompName":"Engineers Construction, Inc.",
             "WorkReason":"Yes",
             "BillAddress":"1 National Life Dr",
             "BillTown":"Montpelier",
             "BillState":"VT",
             "BillZIP":"05604",
             "CompType":"Private",
             "AppName":"Stephen Smith",
             "AppPhone":"802-828-5379",
             "AppEmail":null,
             "WorkRR":"VTRN",
             "WorkTown":"Vergennes",
             "WorkFromMP":94,
             "WorkToMP":null,
             "WorkDuration":"3 hours",
             "WorkStartDate":1469073600000,
             "WorkDescription":"I need to go and fix a thing about the stuff because I need to have a long description text just in case somebody gets a little long winded",
             "WorkEquipment":"Excavator",
             "WorkCompletionDate":1469073600000,
             "WorkAsset":"Rail",
             "RPMApprovalBy":"Kevin Clairmont",
             "RPMComment":"dddddddddddddddddddd",
             "RPMDecisionDate":"9/01/16",
             "RRDecision":"approved"
          },
          "symbol":{
             "color":[
                20,
                175,
                200,
                150
             ],
             "size":17,
             "angle":0,
             "xoffset":0,
             "yoffset":0,
             "type":"esriSMS",
             "style":"esriSMSDiamond",
             "outline":{
                "color":[
                   255,
                   255,
                   255,
                   255
                ],
                "width":1,
                "type":"esriSLS",
                "style":"esriSLSSolid"
             }
          }
       }
    ]

However, the NCAA example JSON looks like this:

    [  
       {  
          "attributes":{  
             "University":"Northern Iowa",
             "WINPER":1088904,
             "Rd_64_Venue":"Quicken Loans Arena",
             "Rd_64_Result":"R",
             "Rd_64_Margin":320,
             "OBJECTID":71
          }
       }
    ]

Why isn't my feature layer being updated by the .applyEdits() request?

ok another difference in the code from the NCAA example:
the example object is updateFeature = features[0] from a featureLayer.selectFeatures query, then the applyEdits is called like this:
updateFeature.getLayer().applyEdits(null, [updateFeature], null)
whereas my feature object is the results.features[0] from a QueryTask, with attributes updated. it is called like
featureLayer.applyEdits(null, [feature], null, callback, errback)
the results is passed to a new Graphic like so:
feature = new Graphic(results.features[0].geometry, symbol, results.features[0].attributes)

Best Answer

Outcome:

It turns out, by capturing data in a plain HTML form, I wasn’t honoring the field settings of the feature class. When sending invalid data into a field, the REST API returns an object reporting on the outcome.
Here’s the response:

    {
       "addResults":[

       ],
       "updateResults":[
          {
             "objectId":1300,
             "globalId":null,
             "success":false,
             "error":{
                "code":1000,
                "description":"Conversion failed when converting the nvarchar value 'Mark Fitzgerald' to data type int."
             }
          }
       ],
       "deleteResults":[

       ]
    }

The above error code is not caught in a try/catch, nor reported in the errback

From rene: use layer.applyEdits().then().otherwise(). technically it didn’t error out, it failed. that’s different. that’s why the success property is sent.
That may be some internal workings of the FeatureLayer, I’m not sure. the REST API don’t care (see Apply Edits Feature Service Layer in REST API docs)
The results of the applyEdits will not return as an error to be caught because not everything may in the applyEdits may fail. Some adds/updates/deletes may be fine, when others may fail for some reason
That’s why the success property, error and codes and sent back
the errback and otherwise for Deferred error catcher will only kick in if there is an issue connecting wth the service
try/catch only works for unhandled exceptions, but not for unhandled Promise errors

The lesson: Validate your inputs!

Related Question