Select to view content in your preferred language

How to Delete Records from a Feature Layer?

4029
9
01-08-2013 03:40 PM
jonathanlee1
Emerging Contributor
I am trying to delete some records from a feature layer, but I kept getting the error of invalid parameters from the errback.

Below is my code:

function deleteRecords()
{
var incidentId = 2;
var queryTaskDeleteRecords= new esri.tasks.QueryTask(FEATURE_SERVER+"/"+LAYER_V_RECORDS);
var queryDeleteRecords = new esri.tasks.Query();
queryDeleteRecords.outSpatialReference = map.spatialReference; 
queryDeleteRecords.returnGeometry = true;
queryDeleteRecords.outFields = ["*"];
queryDeleteRecords.where = FIELD_V_RECORDS_INCIDENTID + " = " + incidentId ; 
queryTaskDeleteRecords.execute(queryValveRec,deleteRecordsResults); 

}

function deleteRecordsResults(results)
{
var graphicArray = []; 
var valve_suggest_new = new esri.layers.FeatureLayer( FEATURE_SERVER+"/"+LAYER_V_RECORDS,{
        outFields:["*"]
    });

for (var i = 0; i < results.features.length; i++)
{
    var attributes = {};
    attributes[FIELD_V_RECORDS_OBJECTID] = results.features.attributes[FIELD_V_RECORDS_OBJECTID];

    var graphic = new esri.Graphic(results.features.geometry, null, attributes);

    graphicArray.push(graphic);

}

alert("graphicArray : " + JSON.stringify(graphicArray));
valve_suggest_new.applyEdits(null, null, graphicArray, function onComplete(adds, updates, deletes)
{
    if (deletes.length > 0)
    {
        alert("deletes : " + JSON.stringify(deletes));
    }
},
function errCallback(err)
{
    alert(err);
});


Is my declaration of the graphic array wrong? I did try deleting it graphic by graphic but it still doesn't work.
0 Kudos
9 Replies
AdrianMarsden
Honored Contributor
I'm trying to do something similar - add a button that deletes all features that meet a entered requirement - not having much luck - I think it is something in the query- not got as far as actually sending the deletes but this is what I have

function deleteRecords(){
    var queryTask = new esri.tasks.QueryTask("http://<server stuff>/FeatureServer/0");


    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = false;
    query.outFields = ["PROCESS"];


    query.outSpatialReference = { "wkid": 27700 };


    query.where = "PROCESS = 'Report Dead Animal'";


    queryTask.execute(query,doDelete);


}


function doDelete(featureset) {
    console.debug(featureset.features)
    var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255,255,255,0.35]), 1),new dojo.Color([125,125,125,0.35]));
          
    //QueryTask returns a featureSet.  Loop through features in the featureSet and add them to the map.
    dojo.forEach(featureSet.features,function(feature){
        alert("yay")
        var graphic = feature;
        graphic.setSymbol(symbol);
        graphic.setInfoTemplate(infoTemplate);
            
        map.graphics.add(graphic);
    });
}


The "console.debug(featureset.features)" shows 5 objects, which is correct, but then I get no alert("yay") - which I should.

Ideas?

ACM
0 Kudos
DianaBenedict
Frequent Contributor
I think that all you need to do is:
results.features

not the graphic only

Below is how I successfully delete features using a graphic array

var graphics = sLayerColl.features;
editFeatureLayer.applyEdits(null, null, graphics, applyEditsSuccess, applyEditsError);

by default the returned set of features is already an array...

Also, I have had issues when I have not added the featurelayer to the map prior to doing any processing but I might be incorrect with that assumption.  I say this because I notice that in your code sample, you get a NEW featurelayer but I do not see that you add it to the map. Again, not 100% sure of this but I have encountered unexpected results when I do not add the featurelayer that I want to edit the map.
0 Kudos
AdrianMarsden
Honored Contributor
Diana - thanks for the advice to the OP - My code is similar now after your last answer -
function deleteRecords()
{
    var queryTask = new esri.tasks.QueryTask("http://xxx/arcgis/rest/services/LIVEinternal/DeleteLaganCase/FeatureServer/0");


    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = false;
    query.outFields = ["*"];


    query.outSpatialReference = { "wkid": 27700 };


    query.where = "PROCESS = 'Report Dead Animal'";


    queryTask.execute(query,doDelete);


}


function doDelete(featureset) {
    var pointsOfInterestD = new esri.layers.FeatureLayer("http://xxx/arcgis/rest/services/LIVEinternal/DeleteLaganCase/FeatureServer/0", {
        mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });
    var graphics = featureset.features;
    console.debug(graphics)
    pointsOfInterestD.applyEdits(null, null, graphics, function onComplete(adds, updates, deletes) {
        console.debug(deletes.length)
        if (deletes.length > 0) {
            alert("deletes : " + JSON.stringify(deletes));
        }
    },
function errCallback(err) {
    alert(err);
});
}




I've added the OP's oncomplete part - number of deletes = 0, no errors.  However, using the same code, but making it an insert works fine.

I'm guessing it is something to do with the OBJECTID, but can't see what  - here's the result from the console when I ask it toreturn the graphic object

[Object, Object]
  • 0: Object
    • attributes: Object
      • CASEID: 101000243048
      • OBJECTID: 13608
      • PROCESS: "Report Dead Animal"
      • __proto__: Object
    • geometry: Object
    • infoTemplate: undefined
    • symbol: undefined
    • __proto__: Object
  • 1: Object
  • length: 2
  • __proto__: Array[0]


Any ideas?

Cheers

ACM

PS using http://xxx/arcgis/rest/services/LIVEinternal/DeleteLaganCase/FeatureServer/0/deleteFeatures

Interface, I can delete the records with the OBJECTID returned - but it fails in the code - so I would say it is a valid OBJECTID and the service allows deletes.
0 Kudos
DianaBenedict
Frequent Contributor
A couple of things to think about

1) it looks like you are not returning the geometry in your Query object? The FeatureLayer.applyEdits(adds, updates, deletes, callback, errback) takes an array of Graphics.  Graphics essentially refers to the your features that have the geometry, attributes, symbology, etc.. Alter your code to return the geometry and try it again.

2) I see that you get an instance of the your feature layer and then perform the query and then call apply edits.  Has the feature layer not been added to your map? Or are you displaying the data as a MapService so users can see the data of interest?  All samples that I see always require you to 1) instantiate the feature layer 2) add it to the map 3) perfrom actions aon the feature layer as needed.  Once I tried manipulating data "behind the scenes" without adding the featureLayer of interest to the map and things just didn't work quite right. Just make sure that you add the FeatureLayer to the map before doing anything to it.

Good luck, I hope this helps

Diana
0 Kudos
AdrianMarsden
Honored Contributor
Cheers - the feature layer I delete from I have set up just for this purpose - the layer the users add records has all the records filtered out (for now), as I don't want a complex edit template - once I have worked out how to delete records without using the editor widget I'll move on to adding them. (and I have tried adding this one to the map as well as per you earlier post 🙂 )

I'm at home now,so can't play with the geometry thing - any good samples you can point to - no problem if not, I'll have a good look later. 

Cheers

ACM

edit Doh! I see what you mean the false in the return geometry - maybe a quick look now.
0 Kudos
AdrianMarsden
Honored Contributor
Nope - my code now looks like

function deleteRecords() {    var queryTask = new esri.tasks.QueryTask("http://xxx/gis2/arcgis/rest/services/LIVEinternal/DeleteLaganCase/FeatureServer/0");




    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = true;
    query.outFields = ["*"];




    query.outSpatialReference = { "wkid": 27700 };




    query.where = "PROCESS = 'Report Dead Animal'";




    queryTask.execute(query, doDelete);




}




function doDelete(featureset) {
    var pointsOfInterestD = new esri.layers.FeatureLayer("http://xxx/arcgis/rest/services/LIVEinternal/DeleteLaganCase/FeatureServer/0", {
        mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
        outFields: ["*"]
    });
    map.addLayers([pointsOfInterestD]);
    var graphics = featureset.features;
    console.debug(graphics)
    pointsOfInterestD.applyEdits(null, null, graphics, function onComplete(adds, updates, deletes) {
        console.debug(deletes.length)
        if (deletes.length > 0) {
            alert("deletes : " + JSON.stringify(deletes));
        }
    },
function errCallback(err) {
    alert(err);
});
}


Still the console.debug(graphics) returns several objects (with geometry and attributes), but the console.debug(deletes.length) returns 0

very strange
0 Kudos
DianaBenedict
Frequent Contributor
The way I have my edit environment set up is as follow:
1) add layers of interest to the map
- MapService (reference layer)
- FeatureService (edit/operational layers) - dojo.require("esri.layers.FeatureLayer");
- map.addLayers(yourlayerarray);
2) dojo.connect map onLayersAdd to make sure the data has been loaded up
3) maybe within the dojo.connect above you can add the selectFeatures if it is not hooked up to some user UI tool
4) Use the FeatureLayer.queryFeatures(query, callback, errback) method. You do not need to use the QueryTask since query functionality is already exposed in the FeatureLayer object.
5) add your callback for onSelectionComplete and get your graphics then pass them on to your applyEdits

//updated your callback function a little to coincide with one of the expected syntax
pointsOfInterestD.applyEdits(null, null, graphics, function(adds, updates, deletes) {
        console.debug(deletes.length)
        if (deletes.length > 0) {
            alert("deletes : " + JSON.stringify(deletes));
        }
    },
function errCallback(err) {
    alert(err);
});
0 Kudos
AdrianMarsden
Honored Contributor
Ah - that looks sound - I see now not needing the querytask is a good thing - I'll try tomorrow.

Many thanks
ACM
0 Kudos
AdrianMarsden
Honored Contributor
Diana - success! 😉

function deleteRecords() {
    //build query filter
    var query = new esri.tasks.Query();
    query.returnGeometry = true;
    query.outFields = ["*"];
    query.outSpatialReference = { "wkid": 27700 };
    query.where = "PROCESS = 'Report Dead Animal'";
    // Query for the features with the given object ID
    pointsOfInterestD.queryFeatures(query, function (featureSet) {
        var graphics = featureSet.features;   
        pointsOfInterestD.applyEdits(null, null, graphics, function (deletes) {
            console.debug(deletes.length)
        },
        function errCallback(err) {
            alert(err);
        })
    });
}


Deletes those features I need - as you suggested the feature layer is define and added outside this function (in the init function)

I now need to plumb in the exact delete requirements (as all the dead animals are gone!)  - sorry, but as I'm not the OP I can't mark as answered, but I am sure this will meet the OP's requirements as well.  Many thanks for your help.

ACM

PS - FYI after getting working I removed the map.adlayers for my featurelayer and it still works.
0 Kudos