Hello -
I've had a web app that edits a polygon feature layer for over a year now and I just noticed that updating attributes is not working. I followed this sample very closely: Using the attribute inspector | ArcGIS API for JavaScript . I use layer.applyEdits(null, [feature], null) and confirmed in the console that the feature I pass in to be updated has the edits that I want to apply.
If I listen for the 'edits-complete' event I get the results and that the update was a success. I'm not getting any errors. There is an "OBJECTID" field that is a number. But the edits are not saving to the layer-- if I save the edits, close the attribute inspector and then re-open the attribute inspector, the edits are gone.
Does anyone have any debugging ideas? Without error messages I've hit a wall on what to check.
Thanks!
saveClickFunction : function(feature, attIn) { var saveClickDeferred = new Deferred; var layer = feature.getLayer(); // Checking the correct layer is being targeted console.log("LAYER", layer); // Checking the feature shows the correct edits console.log('FEATURE', feature); // Check there's an objectid field console.log('obid', feature.attributes.OBJECTID); // Look at the update results on.once(layer, 'edits-complete', function(re) { console.log("Successful update?", re.updates[0].success); attIn.refresh(); layer.refresh(); saveClickDeferred.resolve('Done'); }); var updateDeferred = layer.applyEdits(null, [feature], null); return saveClickDeferred.promise; }
Could you also share the part where you call or setup the click event to call the saveClickFunction function.
Sure, below. There's also a huge amount of code where I initialize editing...I could share it but it's hard to read
// Save button var saveID = arc.edit.modules.attributes.addSaveButton(); on(saveID, "click", function(evt) { var clickWait = arc.edit.modules.attributes.saveClickFunction(arc.edit.variables.updateFeature, arc.edit.variables.attInspector); clickWait.then(function(end) { if (arc.dgrid.variables.selectedLayerID == 'CDB') { arc.dgrid.modules.dgrid.refresh(arc.layers.variables.layers.cdb, arc.tracking.variables.storeGraphics, arc.graphics.modules.symbolsRenderers.symbols(), arc.map.modules.map, arc.dgrid, arc.popups.variables.exclude); } }); });
I asked this part of code to understand how the feature parameter was passed. Well I would suggest you to debug and see if the attributes are actually changed/updated before the applyedits are called. That way we can be sure that it is not updating.
In the sample, the main part where the attributes are updates is
attInspector.on("attribute-change", function(evt) { //store the updates to apply when the save button is clicked updateFeature.attributes[evt.fieldName] = evt.fieldValue; });
ensure that the correct feature is updated in that event. Otherwise, you will be just passing the original feature and it will send success without updating any values.
Hope this was helpful.
Thejus
Thanks Thejus - Yes I am updating the feature when it changes in the attribute inspector...but your comment made me realize that maybe I wasn't doing it in time...
I think there is in fact a significant enough delay when the updateFeature object is revised with new edits that I am clicking 'Save' before the object is revised! If I click another field before clicking save then that gives the object enough time to update.
I confirmed this when I remembered that if I print an entire object to Chrome's console, Chrome keeps it "live" and updates it when values in the object change in the future.
In my original code I was printing the whole updateFeature object to the console. After the applyEdits failed I'd go to the console, and the correct feature object with updates was there! Baffling. But since the Chrome console keeps that reference to the whole object, even though there was a delay, by the time I checked the console it had revised the object in the console with the edits. So I thought the correct feature was being applied....but I changed the console output to be an actual attribute variable, which the Chrome console will not retroactively update, and in fact the edit wasn't there! So I need to create a Deferred or something to make sure a user cannot apply edits until the feature object is fully updated.
Code in main.js that updates with a delay:
arc.edit.variables.attInspector.on("attribute-change", function(evt) { //store the updates to apply when the save button is clicked arc.edit.variables.updateFeature.attributes[evt.fieldName] = evt.fieldValue; });
code in editAttributes.js originally
saveClickFunction : function(feature, attIn) { ... // !!! Chrome console was retroactively updating this object // making it seem like edits had been applied console.log('FEATURE',feature); ... },
Edited code in editAttributes.js revealing the object not updating in time to be saved:
saveClickFunction : function(feature, attIn) { ... // !!! Chrome console won't retroactively update this variable // Revealed it was not updating quickly enough to be caught by the "Save" click // therefore not applying any edits console.log('FEATURE',feature.attributes.developer); ... },
You could enable the save button in attribute-change event, to ensure that the changes are applied before user can click save.
That's a great idea.
I'm testing things now and realizing if I type in just one field, the 'attribute-change' event doesn't fire. It fires when I switch fields, or when I hit save.
In the sample here ArcGIS API for JavaScript Sandbox, I can edit one field and it DOES save.
Maybe because I have more complicated code, the event fires when I hit save, but the edits don't get populated to the updateFeature object in time...but in the sample, the smaller code base allows them to get populated?
For now I am just adding in a timeout to the saveClick function to give the updateFeature object a chance to update.
So the behavior is erratic. However I can consistently save edits if I click in more than one field of the attribute inspector before clicking save. When I edit a single field it usually does not save...
Is there a way to make a field active by default so that any field click would be the the second field ?