Skip to content

Commit

Permalink
feat(add applyEdits function): adds \applyEdits()\ to feature-layer…
Browse files Browse the repository at this point in the history
… for bulk crud transactions.
  • Loading branch information
COV-GIS committed Nov 14, 2019
1 parent 9e755b7 commit ec36841
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 2 deletions.
90 changes: 90 additions & 0 deletions packages/arcgis-rest-feature-layer/src/applyEdits.ts
@@ -0,0 +1,90 @@
/* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

import {
request,
cleanUrl,
appendCustomParams
} from "@esri/arcgis-rest-request";

import { IFeature } from "@esri/arcgis-rest-types";

import { ISharedEditOptions, IApplyEditsResult } from "./helpers";

/**
* Apply edits request options. See the [REST Documentation](https://developers.arcgis.com/rest/services-reference/apply-edits-feature-service-layer-.htm) for more information.
*
*/
export interface IApplyEditsOptions extends ISharedEditOptions {
/**
* Array of JSON features to add.
*/
adds?: IFeature[];
/**
* Array of JSON features to update.
*/
updates?: IFeature[];
/**
* Array of objectIds or globalIds to delete.
*/
deletes?: number[] | string[];
/**
* When set to true, the features and attachments in the adds, updates, deletes, and attachments parameters are identified by their globalIds.
*/
useGlobalIds?: boolean;
/**
* Use the attachments parameter to add, update or delete attachments. Applies only when the useGlobalIds parameter is set to true.
* See [attachment](https://developers.arcgis.com/rest/services-reference/apply-edits-feature-service-layer-.htm) param details.
*/
attachments?: {
adds?: any[];
updates?: any[];
deletes?: string[];
};
}

/**
* ```js
* import { applyEdits } from '@esri/arcgis-rest-feature-layer';
* //
* applyEdits({
* url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/ServiceRequest/FeatureServer/0",
* adds: [{
* geometry: { x: -120, y: 45, spatialReference: { wkid: 4326 } },
* attributes: { status: "alive" }
* }],
* updates: [{
* attributes: { OBJECTID: 1004, status: "alive" }
* }],
* deletes: [862, 1548]
* })
* .then(response)
* ```
* Apply edits request. See the [REST Documentation](https://developers.arcgis.com/rest/services-reference/apply-edits-feature-service-layer-.htm) for more information.
*
* @param requestOptions - Options for the request.
* @returns A Promise that will resolve with the applyEdits response.
*/
export function applyEdits(
requestOptions: IApplyEditsOptions
): Promise<IApplyEditsResult> {
const url = `${cleanUrl(requestOptions.url)}/applyEdits`;

// edit operations are POST only
const options = appendCustomParams<IApplyEditsOptions>(
requestOptions,
[
"adds",
"updates",
"deletes",
"useGlobalIds",
"attachments",
"gdbVersion",
"returnEditMoment",
"rollbackOnFailure"
],
{ params: { ...requestOptions.params } }
);

return request(url, options);
}
21 changes: 21 additions & 0 deletions packages/arcgis-rest-feature-layer/src/helpers.ts
Expand Up @@ -39,6 +39,27 @@ export interface IEditFeatureResult {
success: boolean;
}

/**
* `globalId` always returned with attachments via apply edits.
*/
export interface IApplyEditsAttachmentResult extends IEditFeatureResult {
globalId: string;
}

/**
* Apply edits result Object.
*/
export interface IApplyEditsResult {
addResults?: IEditFeatureResult[];
updateResults?: IEditFeatureResult[];
deleteResults?: IEditFeatureResult[];
attachments?: {
addResults?: IApplyEditsAttachmentResult[];
updateResults?: IApplyEditsAttachmentResult[];
deleteResults?: IApplyEditsAttachmentResult[];
};
}

/**
* Common add, update, and delete features options.
*/
Expand Down
1 change: 1 addition & 0 deletions packages/arcgis-rest-feature-layer/src/index.ts
Expand Up @@ -5,6 +5,7 @@ export * from "./query";
export * from "./add";
export * from "./update";
export * from "./delete";
export * from "./applyEdits";
export * from "./getAttachments";
export * from "./addAttachment";
export * from "./updateAttachment";
Expand Down
69 changes: 67 additions & 2 deletions packages/arcgis-rest-feature-layer/test/crud.test.ts
@@ -1,10 +1,11 @@
/* Copyright (c) 2018 Environmental Systems Research Institute, Inc.
/* Copyright (c) 2018-2019 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

import {
addFeatures,
updateFeatures,
deleteFeatures,
applyEdits,
IDeleteFeaturesOptions,
IUpdateFeaturesOptions
} from "../src/index";
Expand All @@ -14,7 +15,8 @@ import * as fetchMock from "fetch-mock";
import {
addFeaturesResponse,
updateFeaturesResponse,
deleteFeaturesResponse
deleteFeaturesResponse,
applyEditsResponse
} from "./mocks/feature";

const serviceUrl =
Expand Down Expand Up @@ -127,4 +129,67 @@ describe("feature", () => {
fail(e);
});
});

it("should return objectId of the added, updated or deleted feature(s) and a truthy success", done => {
const requestOptions = {
url: serviceUrl,
adds: [
{
geometry: {
x: -9177311.62541634,
y: 4247151.205222242,
spatialReference: {
wkid: 102100,
latestWkid: 3857
}
},
attributes: {
Tree_ID: 102,
Collected: 1349395200000,
Crew: "Linden+ Forrest+ Johnny"
}
}
],
updates: [
{
attributes: {
OBJECTID: 1001,
Crew: "Tom+ Patrick+ Dave"
}
}
],
deletes: [455]
};
fetchMock.once("*", applyEditsResponse);
applyEdits(requestOptions)
.then(response => {
expect(fetchMock.called()).toBeTruthy();
const [url, options]: [string, RequestInit] = fetchMock.lastCall("*");
expect(url).toEqual(`${requestOptions.url}/applyEdits`);
expect(options.method).toBe("POST");
expect(options.body).toContain(
"adds=" +
encodeURIComponent(
'[{"geometry":{"x":-9177311.62541634,"y":4247151.205222242,"spatialReference":{"wkid":102100,"latestWkid":3857}},"attributes":{"Tree_ID":102,"Collected":1349395200000,"Crew":"Linden+ Forrest+ Johnny"}}]'
)
);
expect(options.body).toContain(
"updates=" +
encodeURIComponent(
'[{"attributes":{"OBJECTID":1001,"Crew":"Tom+ Patrick+ Dave"}}]'
)
);
expect(options.body).toContain("deletes=455");
expect(response.addResults[0].objectId).toEqual(2156);
expect(response.addResults[0].success).toEqual(true);
expect(response.updateResults[0].objectId).toEqual(1001);
expect(response.updateResults[0].success).toEqual(true);
expect(response.deleteResults[0].objectId).toEqual(455);
expect(response.deleteResults[0].success).toEqual(true);
done();
})
.catch(e => {
fail(e);
});
});
});
21 changes: 21 additions & 0 deletions packages/arcgis-rest-feature-layer/test/mocks/feature.ts
Expand Up @@ -215,6 +215,27 @@ export const deleteAttachmentsResponse = {
]
};

export const applyEditsResponse = {
addResults: [
{
objectId: 2156,
success: true
}
],
updateResults: [
{
objectId: 1001,
success: true
}
],
deleteResults: [
{
objectId: 455,
success: true
}
]
};

export const genericInvalidResponse = {
error: {
code: 400,
Expand Down

0 comments on commit ec36841

Please sign in to comment.