Using FeatureLayer.applyedits() to save multiple graphics at once

4915
3
Jump to solution
10-08-2014 10:15 AM
MS
by
New Contributor III

Hi, in my app I need to allow the user to perform edits, then on a certain button click save all of the edits at once.

Environment: ArcGIS 10.2.2, JSAPI 3.10

I'm first trying this with 'adds' only, and I cannot seem to get it to work properly.  Everything saves fine when I call applyedits - I can see the correct 'addResults' response array coming back from the server through the FireFox network tab - and I can see in the database that all of the features are saved.  Also, when I save just one feature, I have no problems at all.  However, whenever I try to pass in more than one graphic to applyEdits, everything saves to the database, but the callback function always uses the error handler and shows the following error:

TypeError: n is undefined

Stack trace:

t<._editHandler@http://myserver/ArcGisJsApi/library/3.10compact/js/esri/layers/FeatureLayer.js:80:386

t<.applyEdits/<.load@http://myserver/ArcGisJsApi/library/3.10compact/js/esri/layers/FeatureLayer.js:43:64

C/<@http://myserver/ArcGisJsApi/library/3.10compact/init.js:581:241

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:219

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:401

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:401

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

e/<@http://myserver/ArcGisJsApi/library/3.10compact/init.js:577:249

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:219

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:1

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:1

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:401

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

c@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:401

d@http://myserver/ArcGisJsApi/library/3.10compact/init.js:74:10

.cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://myserver/ArcGisJsApi/library/3.10compact/init.js:75:350

.cache["dojo/_base/xhr"]/</b.xhr/<@http://myserver/ArcGisJsApi/library/3.10compact/init.js:191:298

.cache["dojo/Deferred"]/</k@http://myserver/ArcGisJsApi/library/3.10compact/init.js:195:429

.cache["dojo/Deferred"]/</r@http://myserver/ArcGisJsApi/library/3.10compact/init.js:195:357

.cache["dojo/Deferred"]/</f/this.resolve@http://myserver/ArcGisJsApi/library/3.10compact/init.js:197:441

.cache["dojo/Deferred"]/</a@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:309

.cache["dojo/Deferred"]/</k@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:70

.cache["dojo/Deferred"]/</r@http://myserver/ArcGisJsApi/library/3.10compact/init.js:195:357

.cache["dojo/Deferred"]/</f/this.resolve@http://myserver/ArcGisJsApi/library/3.10compact/init.js:197:441

.cache["dojo/Deferred"]/</a@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:309

.cache["dojo/Deferred"]/</k@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:103

.cache["dojo/Deferred"]/</r@http://myserver/ArcGisJsApi/library/3.10compact/init.js:195:357

.cache["dojo/Deferred"]/</f/this.resolve@http://myserver/ArcGisJsApi/library/3.10compact/init.js:197:441

.cache["dojo/Deferred"]/</a@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:309

.cache["dojo/Deferred"]/</k@http://myserver/ArcGisJsApi/library/3.10compact/init.js:196:70

.cache["dojo/Deferred"]/</r@http://myserver/ArcGisJsApi/library/3.10compact/init.js:195:357

.cache["dojo/Deferred"]/</f/this.resolve@http://myserver/ArcGisJsApi/library/3.10compact/init.js:197:441

m@http://myserver/ArcGisJsApi/library/3.10compact/init.js:157:96

f@http://myserver/ArcGisJsApi/library/3.10compact/init.js:160:510

I can see through console.log() that every second element in the graphics array that was passed to applyedits has been removed after calling applyedits, ie if I have six features to save from a graphics array [0,1,2,3,4,5], 1,3,5 will remain and 0,2,4 are removed.  I don't know if applyedits is supposed to try to remove these features or not once the edit is complete?  I'm wondering if it's trying to delete all six by array values but when the first (0) is deleted, it then tries to delete at position (1), when it should be deleting from position 0 all six times.

Anyway, how do I resolve being able to save an array of graphics to a feature layer?  Every editing example I've seen just has the user saving one graphic at a time, even though applyedits allows you to pass in an array of graphics.

My relevant code:

Where I create the FeatureLayer:

this.fLayer = new FeatureLayer("http://myagsserver/arcgis/rest/services/Projects/FeatureServer/0", {

    mode: FeatureLayer.MODE_SNAPSHOT,

    outFields: ["*"]

});

Where I create the GraphicsLayer to intially add graphics to:

this.pointGraphics = new GraphicsLayer({

    id: 'distributionGraphics_point',

    title: 'Draw Graphics'

});

           

this.pointSelectionSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, this.colors.pointSize, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color(this.colors.pointSelectionStroke), 1), new Color(this.colors.pointSelectionFill));

this.pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, this.colors.pointSize, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color(this.colors.pointStroke), 1), new Color(this.colors.pointFill));

this.pointRenderer = new SimpleRenderer(this.pointSymbol);

this.pointGraphics.setRenderer(this.pointRenderer);

this.map.addLayer(this.pointGraphics);

When I draw a point on the map:

onDrawToolbarDrawEnd: function (evt) {

    var graphic;

    switch (evt.geometry.type) {

        case 'point':

            var attributes = {

                "attr1": 123,

                "attr2": 456

            };

            graphic = new Graphic(evt.geometry, null, attributes);

            this.pointGraphics.add(graphic);

            break;

        case 'polyline':

            graphic = new Graphic(evt.geometry);

            this.polylineGraphics.add(graphic);

            break;

        case 'polygon':

            graphic = new Graphic(evt.geometry, null, {

            ren: 1

            });

            this.polygonGraphics.add(graphic);

            break;

        default:

    }

}

Where I make the applyEdits call:

this.fLayer.applyEdits(this.pointGraphics.graphics, null, null, function (add, update, del) {

    console.log('apply edits success');

}, function (error) {

    console.log('apply edits failure');

    console.log(error);

});

Thanks!

0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor

Here's a link to a sample that uses applyEdits to add an array of graphics.

Feature collection | ArcGIS API for JavaScript

View solution in original post

0 Kudos
3 Replies
MS
by
New Contributor III

I ended up using code similar to this - a different loop for update / delete graphics:

array.forEach(this.pointGraphicsToAdd.graphics, lang.hitch(this, function (pointGraphic) {

    updates.push(this.fLayer.applyEdits([pointGraphic], null, null, function (add, update, del) {

    }, function (error) {

        console.log('apply edits failure');

        console.log(error);

    }));

}))

It's not great code and I'd hardly call it an 'answer', but sending a true array doesn't seem to actually work, so I'm stuck with that.

0 Kudos
KellyHutchins
Esri Frequent Contributor

Here's a link to a sample that uses applyEdits to add an array of graphics.

Feature collection | ArcGIS API for JavaScript

0 Kudos
MS
by
New Contributor III

Hi Kelly

I took a look at the example you gave - then tried pushing my graphics to a separate array and applying edits on the new array instead.  It works now, not sure if that was the issue, or if I fixed it through some of the other new code I've built since.  Either way, thanks for the example.

0 Kudos