Skip to content

By default, custom data providers created using the CDF command line tool include only the Query capability. However, you can extend a custom data provider to allow for the Editing capability and implement the applyEdits operation on the custom data feature service. After creating a custom data provider with the CDF command line tool, follow the steps below to configure it for edit capability.

Basic Provider Configuration

  1. Open the providers/your-provider-name/cdconfig.json file. Find the line: "editingEnabled": false and change the value to true. This enables the applyEdits routes for this provider and allows for Editing to be added to any associated feature service's capabilities.

  2. Open the model.js file in the providers/your-provider-name/src directory. In the Model class, create the getMetadata() method. This method will minimally return inputCrs, which referes to the WKID that represents the crs of the data returned by getData(). In most cases, this is the crs the remote data are stored in. Setting the inputCrs ensures that your data are accurately reprojected.

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    async getMetadata() {
        return {
            idField: 'id',
            inputCrs: 4326
        }
    }
  3. Open the model.js file in the providers/your-provider-name/src directory. In the Model class, create the editData() method. At this point, the code becomes specific to your implementation, but refer below basic, sample editData() method that calls a user-implemented helper function(s).

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    async editData(req, editData) {
    
      // assign database and collection name from service parameters
      const databaseName = req.params.dbName;
      const collectionName = req.params.collectionName;
    
      const database  = this.#client.db(databaseName);
      const collection = database.collection(collectionName);
    
      let applyEditsResponse = {}  // initialize the response object
    
      // call the necessary functions to handle the edits
      applyEditsResponse = await performEdits(collection, editData);
    
      return applyEditsResponse;
    
    }

The editData() function takes two parameters - the req Express object and the editData object that contains the incoming edits request.

Understanding the applyEdits API Specification

The editData method must be written to handle requests and return responses that conform to a slightly modified version of the applyEdits REST API specification. The custom data feeds framework modifies the incoming request, whether it is layer-level or service-level to single specification. This simplifies development of the custom data provider code by relieving the developer of needing to handle layer ids and write extra code to conform to the applyEdits REST API specification. The custom data feeds framework handles matching specific edit requests to the appropriate layer ids when the final response is constructed.

An overview of the modified specification is provided below. For complete details on the structure of requests and responses, refer to the REST API specification. Additionally, see this Walkthrough topic for an example of how to implement these details in a custom data provider.

Request specification

The editData object is available in the editData() method and contains three top-level properties: adds, updates, deletes. Each parameter is an array:

  • adds and updates: Arrays of objects where each objects contains geometry and/or attributes.
  • deletes: An array of object IDs.

Example editData object:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    {
        "adds": [
            {
                "geometry": {
                    "x": -12246623.482500909,
                    "y": 6274905.896395514,
                    "spatialReference": {
                        "wkid": 102100,
                        "latestWkid": 3857
                    }
                },
                "attributes": {
                    "fireId": "C3PO",
                    "fireName": "Golden Fire",
                    "fireType": "Wild",
                    "acres": "4682"
                }
            }
        ],
        "updates":[
            {
                "geometry": {
                    "x": -12345678.123456789,
                    "y": 6543210.987654321,
                    "spatialReference": {
                        "wkid": 102100,
                        "latestWkid": 3857
                    }
                },
                "attributes": {
                    "OBJECTID": 99,
                    "fireId": "R2D2",
                    "fireName": "Silver Blaze",
                    "fireType": "Controlled",
                    "acres": "2500"
                }
            }
        ],
        "deletes": [4692,5663]
    }

Response specification

The response object for the applyEdits operation is returned from the editData() method. The developer is responsible for adhering to the specification. It includes three arrays: addResults, updateResults, and deleteResults. Each array contains objects that minimally include the objectId and a success status (true or false). The arrays should be empty if no edits were requested.

Example:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
    "addResults": [
        {
            "objectId": 621431404,
            "success": true
        }
    ],
    "updateResults": [
        {
            "objectId": 99,
            "success": true
        }
    ],
    "deleteResults": [
        {
            "objectId": 4692,
            "success": false,
            "error": {
                "code": 1018,
                "description": "Failed to delete."
            }
        },
        {
            "objectId": 5663,
            "success": true,
        }
    ]
}

Important Points

Custom data providers with edit capability require additional considerations for maintaining data integrity and accessibilty. At a minimum, this involves understanding the spatial reference and data structure of the remote data source. The metadata provided with the returned GeoJSON in the provider will also impact which attributes are editable and influence how ArcGIS clients configure editing widgets.

Spatial Reference

Once data are sent to the client, reprojections may occur based on the client’s default behavior or user preferences. Edits may be requested in a spatial reference that differs from the data source. It is highly important that your code makes use of the getMetadata() method and returns the correct inputCrs. If you do not use this method, you must create your own reprojection logic using tools such as @esri/proj-codes and proj4.

ObjectId

To be editable, features in the remote data source must include an attribute that meets the requirements for an esriFieldTypeOID. This attribute must be an integer no larger than 64 bits. You cannot allow custom data feeds to create an autogenerated objectId for you and have a provider that supports editing. For details, refer to the CDF API Reference documentation on the idField metadata property.

Templates

Templates are essential for customizing editing widgets in ArcGIS clients. By using custom templates, you can specify which attributes are visible for editing, set default values, and apply other customizations. Refer to the CDF API Reference documentation on the templates metadata property.

fields Metadata

To make an attribute editable, set the editable property in the fields metadata. This allows fine-grained control over which feature attributes are available for editing. See the CDF API Reference documentation on the fields metadata property.

Error Codes

Refer to the ArcGIS REST documentation for Feature Service Error Codes. Generally, the error codes that your provider should return are 1017 for an insert error, 1018 for a delete error, and 1019 for an update error.

Optional Parameters: returnEditResults and rollbackOnFailure

The returnEditsResults parameter is not currently supported for custom data feature services. The response that is returned from the editData() method is always expected to have a result per edit. {"success": <true|false>} is not a valid response. The custom data feeds framework has no interaction with the rollbackOnFailure parameter and does not modify the response based on this parameter. It simply passes the parameter and its value through on the req.params object. It is up to the developer honor the parameter and perform their on transaction logic before returning the response. Full results for each edit is expected in accordance with the specification shown above.

The editingEnabled Property and Service capabilities

The provider's editingEnabled property can have downstream influence on associated custom data feature services.

  • When a custom data provider with the property "editingEnabled": true is registered and an associated service is created, the service will not automatically have Editing as a capability. This must be turned on through the Admininstrative API or through Portal item settings.
  • When a custom data provider with the property "editingEnabled": true is used to update an existing provider, associated service(s) will not automatically have Editing as a capability. This must be turned on through the Admininstrative API or through Portal item settings.
  • When a custom data provider with the property "editingEnabled": false is used to update an existing provider, all associated service(s) will automatically have Editing removed as a capability. They will all become read-only.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.