.applyEdits not updating feature service layer

694
6
Jump to solution
05-16-2022 01:49 PM
JamesCrandall
MVP Frequent Contributor

WAB Dev 2.19 / JavaScript 3.x

I have a custom widget with a button click that attaches to the reply_click() function below.  It successfully applies a query to select the feature (via attribute query), sets up a graphic to act as a highlight around the selected point feature and I can confirm the "selGraphic" that is created has the correct geometry and attributes.

What I am trying to implement is a way for the user to edit ("move" only) that selected graphic and then update the underlying layer.layerObject.selectFeatures with the graphic that was "moved" by the user.

I'm not getting any errors and the layer.layerObject.applyEdits() doesn't seem to choke or have any issues, however no edits are actually applied.  I've tried several variations of the applyEdits() method with similar results, all of these do nothing:

layer.layerObject.applyEdits(selGraphic, null, features[0])

layer.layerObject.applyEdits([selGraphic], null, features[0])

layer.layerObject.applyEdits([selGraphic], [], features[0])

layer.layerObject.applyEdits([selGraphic], null, [features[0]])

Any guidance is appreciated!

 

 

        reply_click: function (e) {  
            
            //console.log(e.target.id)
            this.map.itemInfo.itemData.operationalLayers.forEach(layer => {
                if (layer.layerObject) {
                    if (layer.title === "Water Use Application Facilities") {                        
                        var queryTask = new QueryTask(layer.layerObject)
                        var query = new Query();
                        query.returnGeometry = true;
                        query.outFields = ['*']
                        query.where = "facilityId = '" + e.target.id + "'"                                           
                        
                        layer.layerObject.selectFeatures(query).then(function (features) {
                            if (layer.layerObject.geometryType === 'esriGeometryPoint' && features.length === 1) {
                                
                                this.map.centerAt(features[0].geometry);
                                this.map.graphics.clear();
                                var selSymbolJson = {
                                    "color": [
                                        0,
                                        0,
                                        0,
                                        0
                                    ],
                                    "size": 30.5,
                                    "angle": 0,
                                    "xoffset": 0,
                                    "yoffset": 0,
                                    "type": "esriSMS",
                                    "style": "esriSMSCircle",
                                    "outline": {
                                        "color": [
                                            0,
                                            255,
                                            250,
                                            255
                                        ],
                                        "width": 2.50,
                                        "type": "esriSLS",
                                        "style": "esriSLSSolid"
                                    }
                                }
                                var attributes = {};
                                attributes['appId'] = features[0]['attributes'].appId //this.appId
                                attributes['facilityId'] = features[0]['attributes'].facilityId
                                attributes['facilityType'] = features[0]['attributes'].facilityType
                                attributes['facilityName'] = features[0]['attributes'].facilityName
                                attributes['permitId'] = features[0]['attributes'].permitId

                                var selGraphic = new Graphic(features[0].geometry, symbolJsonUtils.fromJson(selSymbolJson), attributes)
                                console.log(features[0].geometry)
                                map.graphics.clear();
                                map.graphics.add(selGraphic);
                                
                                this.editToolbar = new Edit(this.map, { allowAddVertices: false });
                                this.editToolbar.activate(Edit.MOVE, selGraphic);

                                this.map.on("click", function (evt) {
                                    layer.layerObject.applyEdits(selGraphic, null, features[0])                                    
                                    
                                    map.graphics.clear();
                                    map.graphics.add(selGraphic);
                                })                                
                            }
                        });
                    }
                }
            })
        }

 

 

0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

If you're using the Edit toolbar, you can listen for the graphic-move-stop event and save it then

View solution in original post

6 Replies
KenBuja
MVP Esteemed Contributor

The last version ("[selGraphic], null, [features[0]]") should be the one that works, since applyEdits requires the parameters to be Graphics arrays. Are you keeping feature[0] so the user sees the original placement of it?

JamesCrandall
MVP Frequent Contributor

Ken -- thanks for the input.

I don't have the full workflow correct I'm sure.  The way I have it currently once the selection is applied the selected feature/graphic is moveable and the new location has the symbology of the graphic (all good so far).  Then when the user click elsewhere (not on the selected graphic), I want the applyEdits to immediately update the feature service with the new point location of the graphic and it's attributes (deleting the original point feature) and the underlying feature service to show the new point.

 

Edit: I'm not sure that simply clicking off / on the map to applyEdits is the best idea.  I mean, that would get invoked anytime a click (identify feature for ex).  I think ideally, I just want to apply the edit immediately after the graphic has been moved.

Hope that makes sense but this is how I understood the various samples out there.  I'm all ears for guidance!

 

Thanks again.

0 Kudos
KenBuja
MVP Esteemed Contributor

If you're using the Edit toolbar, you can listen for the graphic-move-stop event and save it then

JamesCrandall
MVP Frequent Contributor

Great idea.  Thanks for that.  

Looks like I'm close -- there is a new point feature created with all of the correct attributes, however the original point feature that I started with is not deleted. 

        reply_click: function (e) {  

            console.log(e.target.id)
            this.map.itemInfo.itemData.operationalLayers.forEach(layer => {
                if (layer.layerObject) {
                    if (layer.title === "Water Use Application Facilities") {                        
                        var queryTask = new QueryTask(layer.layerObject)
                        var query = new Query();
                        query.returnGeometry = true;
                        query.outFields = ['*']
                        query.where = "facilityId = '" + e.target.id + "'"                                           
                        
                        layer.layerObject.selectFeatures(query).then(function (features) {
                            if (layer.layerObject.geometryType === 'esriGeometryPoint' && features.length === 1) {

                                //var feat = layer.layerObject.getSelectedFeatures();
                                //console.log(features[0])
                                this.map.centerAt(features[0].geometry);
                                this.map.graphics.clear();
                                var selSymbolJson = {
                                    "color": [
                                        0,
                                        0,
                                        0,
                                        0
                                    ],
                                    "size": 30.5,
                                    "angle": 0,
                                    "xoffset": 0,
                                    "yoffset": 0,
                                    "type": "esriSMS",
                                    "style": "esriSMSCircle",
                                    "outline": {
                                        "color": [
                                            0,
                                            255,
                                            250,
                                            255
                                        ],
                                        "width": 2.50,
                                        "type": "esriSLS",
                                        "style": "esriSLSSolid"
                                    }
                                }

                                var attributes = {};
                                attributes['appId'] = features[0]['attributes'].appId //this.appId
                                attributes['reviewStatus'] = features[0]['attributes'].reviewStatus
                                attributes['facilityId'] = features[0]['attributes'].facilityId
                                attributes['facilityType'] = features[0]['attributes'].facilityType
                                attributes['facilityName'] = features[0]['attributes'].facilityName
                                attributes['permitId'] = features[0]['attributes'].permitId
                                attributes['OBJECTID'] = features[0]['attributes'].OBJECTID

                                this.selGraphic = new Graphic(features[0].geometry, symbolJsonUtils.fromJson(selSymbolJson), attributes)

                                this.map.graphics.clear();
                                this.map.graphics.add(selGraphic);
                                this.editToolbar = new Edit(this.map);
                                this.editToolbar.activate(Edit.MOVE, selGraphic);

                                this.editToolbar.on('graphic-move-stop', function (evt) {
                                    var serverSideScratchLayerFacs = new FeatureLayer("urlToEditableFeatureService/FeatureServer/0" + '?token=uV6qzrCtV3hX_4XCqy_u9u3sVAb3QxuT86L1mTwlHdu1lcfPjOrer2vpjXoi61Y3wh8Fz82hsjqlosBKnOsdPF5m3wTW6wF9GmlRLgaPUQk.'); // + window.atob(tok));
                                    var scratchQueryFacs = new Query();
                                    scratchQueryFacs.where = "facilityId = '" + e.target.id + "'"
                                    serverSideScratchLayerFacs.queryFeatures(scratchQueryFacs);
                                    serverSideScratchLayerFacs.selectFeatures(scratchQueryFacs).then(function (features) {

                                        serverSideScratchLayerFacs.applyEdits([selGraphic], null, [features[0]])                                        
                                        this.editToolbar.deactivate()
                                        layer.layerObject.refresh()
                                    })
                                })                                                             
                            }
                        });
                    }
                }
            })
        },

 

 

0 Kudos
KenBuja
MVP Esteemed Contributor

You're running the applyEdit method on a new featurelayer (serverSideScratchLayerFacs), not the layer (layer.layerObject) where the original point feature resides.

JamesCrandall
MVP Frequent Contributor

Yeah, was my oversight when first attempt at this then realized that layer.layerObject is a view only service in the webmap source to this WAB app.  serverSideScratchLayerFacs is the edit service to the same data source.

I still think its close because it does in fact applyEdits and adds the selGraphic point feature with attributes!  But I'm not seeing why features[0] is not getting deleted at the same time.

Thanks again, I'm making progress with you're input!

Edit: final change works to setup applyEdits with the update instead of add/delete.  Ken I used all of your input/posts to solve this so I just marked the one that was super useful to get the correct workflow.  Much appreciated!

This is the last change that worked:

serverSideScratchLayerFacs.applyEdits(null, [selGraphic], null)

 

0 Kudos