mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
Validate features for adds and updates
This commit is contained in:
parent
727a82686e
commit
c75bd479cd
@ -283,45 +283,29 @@ define([
|
|||||||
adds.forEach(function (addEdit) {
|
adds.forEach(function (addEdit) {
|
||||||
var deferred = new Deferred();
|
var deferred = new Deferred();
|
||||||
|
|
||||||
//self._validateFeature(addEdit).then(function(result){
|
|
||||||
// console.log("HELLLLOOOO")
|
|
||||||
//});
|
|
||||||
|
|
||||||
var objectId = this._getNextTempId();
|
var objectId = this._getNextTempId();
|
||||||
addEdit.attributes[this.objectIdField] = objectId;
|
addEdit.attributes[this.objectIdField] = objectId;
|
||||||
|
|
||||||
var thisLayer = this;
|
var thisLayer = this;
|
||||||
|
|
||||||
self._editStore.pushEdit(self._editStore.ADD, this.url, addEdit, function (result, error) {
|
// We need to run some validation tests against each feature being added.
|
||||||
if(result == true){
|
// If graphic doesn't exist return false and we will add a phantom graphic
|
||||||
results.addResults.push({success: true, error: null, objectId: objectId});
|
// If graphic DOES exist then return true and we do not need to add a phantom graphic
|
||||||
|
this._validateFeature(addEdit,this.url,self._editStore.ADD).then(function(result){
|
||||||
|
console.log("EDIT ADD IS BACK!!! " );
|
||||||
|
|
||||||
var phantomAdd = new Graphic(
|
if(result.success){
|
||||||
addEdit.geometry,
|
thisLayer._pushValidatedAddFeatureToDB(thisLayer,addEdit,result.operation,results,objectId,deferred);
|
||||||
self._getPhantomSymbol(addEdit.geometry, self._editStore.ADD),
|
|
||||||
{
|
|
||||||
objectId: objectId
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add phantom graphic to the layer
|
|
||||||
thisLayer._phantomLayer.add(phantomAdd);
|
|
||||||
|
|
||||||
// Add phantom graphic to the database
|
|
||||||
self._editStore.pushPhantomGraphic(phantomAdd, function (result) {
|
|
||||||
if (!result)console.log("There was a problem adding phantom graphic id: " + objectId);
|
|
||||||
console.log("Phantom graphic " + objectId + " added to database as an add.");
|
|
||||||
});
|
|
||||||
|
|
||||||
domAttr.set(phantomAdd.getNode(), "stroke-dasharray", "10,4");
|
|
||||||
domStyle.set(phantomAdd.getNode(), "pointer-events", "none");
|
|
||||||
|
|
||||||
deferred.resolve(result);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// If we can't push edit to database then we don't create a phantom graphic
|
// If we get here then we deleted an edit that was added offline.
|
||||||
results.addResults.push({success: false, error: error, objectId: objectId});
|
// We also have deleted the phantom graphic.
|
||||||
deferred.reject(error);
|
deferred.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},function(error){
|
||||||
|
console.log("_validateFeature: Unable to validate!");
|
||||||
|
deferred.reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
promises.push(deferred);
|
promises.push(deferred);
|
||||||
@ -336,35 +320,24 @@ define([
|
|||||||
|
|
||||||
var thisLayer = this;
|
var thisLayer = this;
|
||||||
|
|
||||||
self._editStore.pushEdit(self._editStore.UPDATE, this.url, updateEdit, function (result, error) {
|
// We need to run some validation tests against each feature being added.
|
||||||
|
// If graphic doesn't exist return false and we will add a phantom graphic
|
||||||
|
// If graphic DOES exist then return true and we do not need to add a phantom graphic
|
||||||
|
this._validateFeature(updateEdit,this.url,self._editStore.UPDATE).then(function(result){
|
||||||
|
console.log("EDIT UPDATE IS BACK!!! " );
|
||||||
|
|
||||||
if(result == true){
|
if(result.success){
|
||||||
results.updateResults.push({success: true, error: null, objectId: objectId});
|
thisLayer._pushValidatedUpdateFeatureToDB(thisLayer,updateEdit,result.operation,results,objectId,deferred);
|
||||||
|
|
||||||
var phantomUpdate = new Graphic(
|
|
||||||
updateEdit.geometry,
|
|
||||||
self._getPhantomSymbol(updateEdit.geometry, self._editStore.UPDATE),
|
|
||||||
{
|
|
||||||
objectId: objectId
|
|
||||||
});
|
|
||||||
thisLayer._phantomLayer.add(phantomUpdate);
|
|
||||||
|
|
||||||
// Add phantom graphic to the database
|
|
||||||
self._editStore.pushPhantomGraphic(phantomUpdate, function (result) {
|
|
||||||
if (!result)console.log("There was a problem adding phantom graphic id: " + objectId);
|
|
||||||
console.log("Phantom graphic " + objectId + " added to database as an update.");
|
|
||||||
});
|
|
||||||
|
|
||||||
domAttr.set(phantomUpdate.getNode(), "stroke-dasharray", "5,2");
|
|
||||||
domStyle.set(phantomUpdate.getNode(), "pointer-events", "none");
|
|
||||||
|
|
||||||
deferred.resolve(result);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// If we can't push edit to database then we don't create a phantom graphic
|
// If we get here then we deleted an edit that was added offline.
|
||||||
results.addResults.push({success: false, error: error, objectId: objectId});
|
// We also have deleted the phantom graphic.
|
||||||
deferred.reject(error);
|
deferred.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},function(error){
|
||||||
|
console.log("_validateFeature: Unable to validate!");
|
||||||
|
deferred.reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
promises.push(deferred);
|
promises.push(deferred);
|
||||||
@ -642,6 +615,154 @@ define([
|
|||||||
|
|
||||||
/* internal methods */
|
/* internal methods */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an UPDATE request to the database after it's been validated
|
||||||
|
* @param layer
|
||||||
|
* @param updateEdit
|
||||||
|
* @param operation
|
||||||
|
* @param resultsArray
|
||||||
|
* @param objectId
|
||||||
|
* @param deferred
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
layer._pushValidatedUpdateFeatureToDB = function(layer,updateEdit,operation,resultsArray,objectId,deferred){
|
||||||
|
self._editStore.pushEdit(operation, layer.url, updateEdit, function (result, error) {
|
||||||
|
|
||||||
|
if(result == true){
|
||||||
|
resultsArray.updateResults.push({success: true, error: null, objectId: objectId});
|
||||||
|
|
||||||
|
var phantomUpdate = new Graphic(
|
||||||
|
updateEdit.geometry,
|
||||||
|
self._getPhantomSymbol(updateEdit.geometry, self._editStore.UPDATE),
|
||||||
|
{
|
||||||
|
objectId: objectId
|
||||||
|
});
|
||||||
|
layer._phantomLayer.add(phantomUpdate);
|
||||||
|
|
||||||
|
// Add phantom graphic to the database
|
||||||
|
self._editStore.pushPhantomGraphic(phantomUpdate, function (result) {
|
||||||
|
if (!result)console.log("There was a problem adding phantom graphic id: " + objectId);
|
||||||
|
console.log("Phantom graphic " + objectId + " added to database as an update.");
|
||||||
|
});
|
||||||
|
|
||||||
|
domAttr.set(phantomUpdate.getNode(), "stroke-dasharray", "5,2");
|
||||||
|
domStyle.set(phantomUpdate.getNode(), "pointer-events", "none");
|
||||||
|
|
||||||
|
deferred.resolve(result);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// If we can't push edit to database then we don't create a phantom graphic
|
||||||
|
resultsArray.addResults.push({success: false, error: error, objectId: objectId});
|
||||||
|
deferred.reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an ADD request to the database after it's been validated
|
||||||
|
* @param layer
|
||||||
|
* @param addEdit
|
||||||
|
* @param operation
|
||||||
|
* @param resultsArray
|
||||||
|
* @param objectId
|
||||||
|
* @param deferred
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
layer._pushValidatedAddFeatureToDB = function(layer,addEdit,operation,resultsArray,objectId,deferred){
|
||||||
|
self._editStore.pushEdit(operation, layer.url, addEdit, function (result, error) {
|
||||||
|
if(result == true){
|
||||||
|
resultsArray.addResults.push({success: true, error: null, objectId: objectId});
|
||||||
|
|
||||||
|
var phantomAdd = new Graphic(
|
||||||
|
addEdit.geometry,
|
||||||
|
self._getPhantomSymbol(addEdit.geometry, self._editStore.ADD),
|
||||||
|
{
|
||||||
|
objectId: objectId
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add phantom graphic to the layer
|
||||||
|
layer._phantomLayer.add(phantomAdd);
|
||||||
|
|
||||||
|
// Add phantom graphic to the database
|
||||||
|
self._editStore.pushPhantomGraphic(phantomAdd, function (result) {
|
||||||
|
if (!result)console.log("There was a problem adding phantom graphic id: " + objectId);
|
||||||
|
console.log("Phantom graphic " + objectId + " added to database as an add.");
|
||||||
|
});
|
||||||
|
|
||||||
|
domAttr.set(phantomAdd.getNode(), "stroke-dasharray", "10,4");
|
||||||
|
domStyle.set(phantomAdd.getNode(), "pointer-events", "none");
|
||||||
|
|
||||||
|
deferred.resolve(result);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// If we can't push edit to database then we don't create a phantom graphic
|
||||||
|
resultsArray.addResults.push({success: false, error: error, objectId: objectId});
|
||||||
|
deferred.reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates duplicate entries. Last edit on same feature can overwite any previous values.
|
||||||
|
* Note: if an edit was already added offline and you delete it then we return success == false
|
||||||
|
* @param graphic esri.Graphic.
|
||||||
|
* @param layerUrl the URL of the feature service
|
||||||
|
* @param operation add, update or delete action on an edit
|
||||||
|
* @returns deferred {success:boolean,graphic:graphic,operation:add|update|delete}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
layer._validateFeature = function (graphic,layerUrl,operation) {
|
||||||
|
|
||||||
|
var deferred = new Deferred();
|
||||||
|
|
||||||
|
var id = layerUrl + "/" + graphic.attributes.objectid;
|
||||||
|
|
||||||
|
self._editStore.getEdit(id,function(success,result){
|
||||||
|
if (success) {
|
||||||
|
switch( operation )
|
||||||
|
{
|
||||||
|
case self._editStore.ADD:
|
||||||
|
// Not good - however we'll allow the new ADD to replace/overwrite existing edit
|
||||||
|
// and pass it through unmodified. Last ADD wins.
|
||||||
|
deferred.resolve({"success":true,"graphic":graphic,"operation":operation});
|
||||||
|
break;
|
||||||
|
case self._editStore.UPDATE:
|
||||||
|
// If we are doing an update on a feature that has not been added to
|
||||||
|
// the server yet, then we need to maintain its operation as an ADD
|
||||||
|
// and not an UPDATE. This avoids the potential for an error if we submit
|
||||||
|
// an update operation on a feature that has not been added to the
|
||||||
|
// database yet.
|
||||||
|
if(result.operation = self._editStore.ADD){
|
||||||
|
graphic.operation = self._editStore.ADD;
|
||||||
|
operation = self._editStore.ADD;
|
||||||
|
}
|
||||||
|
deferred.resolve({"success":true,"graphic":graphic,"operation":operation});
|
||||||
|
break;
|
||||||
|
case self._editStore.DELETE:
|
||||||
|
|
||||||
|
if(result.operation = this._editStore.ADD){
|
||||||
|
// If we are deleting a new feature that has not been added to the
|
||||||
|
// server yet we need to delete it and its phantom graphic.
|
||||||
|
deferred.resolve({"success":false,"graphic":graphic,"operation":operation});
|
||||||
|
}
|
||||||
|
deferred.resolve({"success":true,"graphic":graphic,"operation":operation});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(result == "Id not found"){
|
||||||
|
// Let's simply pass the graphic back as good-to-go.
|
||||||
|
// No modifications needed because the graphic does not
|
||||||
|
// already exist in the database.
|
||||||
|
deferred.resolve({"success":true,"graphic":graphic,"operation":operation});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
deferred.reject(graphic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred;
|
||||||
|
};
|
||||||
|
|
||||||
layer._getFilesFromForm = function (formNode) {
|
layer._getFilesFromForm = function (formNode) {
|
||||||
var files = [];
|
var files = [];
|
||||||
var inputNodes = array.filter(formNode.elements, function (node) {
|
var inputNodes = array.filter(formNode.elements, function (node) {
|
||||||
@ -1316,52 +1437,6 @@ define([
|
|||||||
return dfd.promise;
|
return dfd.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates duplicate entries. Last edit on same feature can overwite any previous values.
|
|
||||||
* @param edit valid internal editsStore edit object.
|
|
||||||
* @returns deferred
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_validateFeature: function (edit) {
|
|
||||||
|
|
||||||
var deferred = new Deferred();
|
|
||||||
this._editStore.getEdit(edit.id,function(success,result){
|
|
||||||
if (success) {
|
|
||||||
switch( edit.operation )
|
|
||||||
{
|
|
||||||
case this._editStore.ADD:
|
|
||||||
// Not good - however we'll allow the new ADD to replace existing edit
|
|
||||||
// and pass it through unmodified. Last ADD wins.
|
|
||||||
deferred.resolve(edit);
|
|
||||||
break;
|
|
||||||
case this._editStore.UPDATE:
|
|
||||||
// If we are doing an update on a feature that has not been added to
|
|
||||||
// the server yet, then we need to maintain its operation as an ADD
|
|
||||||
// and not an update. This avoids the potential for an error if we submit
|
|
||||||
// an update operation on a feature that has not been added to the
|
|
||||||
// database yet.
|
|
||||||
if(result.operation = this._editStore.ADD){
|
|
||||||
edit.operation = this._editStore.ADD;
|
|
||||||
}
|
|
||||||
deferred.resolve(edit);
|
|
||||||
break;
|
|
||||||
case this._editStore.DELETE:
|
|
||||||
|
|
||||||
if(result.operation = this._editStore.ADD){
|
|
||||||
// If we are deleting a new feature that has not been added to the
|
|
||||||
// server yet we need to delete it and its phantom graphic.
|
|
||||||
}
|
|
||||||
deferred.resolve(edit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
deferred.resolve(edit);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return deferred;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated @ v2.5. Internal-use only
|
* Deprecated @ v2.5. Internal-use only
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
|||||||
@ -409,9 +409,82 @@ describe("Offline Editing", function()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async.it("Update new feature offline - point", function(done){
|
||||||
|
|
||||||
|
// Let's make a change to g6 attributes
|
||||||
|
g6.attributes.additionalinformation = "TEST123";
|
||||||
|
var updates = [g6];
|
||||||
|
g_featureLayers[0].applyEdits(null,updates,null,function(addResults,updateResults,deleteResults)
|
||||||
|
{
|
||||||
|
expect(updateResults.length).toBe(1);
|
||||||
|
|
||||||
|
g_editsStore.pendingEditsCount(function(result){
|
||||||
|
|
||||||
|
// Should be the exact same as previous test
|
||||||
|
// An update to a new feature should be a single entry in the database.
|
||||||
|
// We simply update the existing entry with the new information.
|
||||||
|
expect(result).toBe(9);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(error)
|
||||||
|
{
|
||||||
|
expect(true).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async.it("validate non-existent feature - ADD", function(done){
|
||||||
|
|
||||||
|
var testGraphic = new g_modules.Graphic({"geometry":{"x":-109100,"y":5137000,"spatialReference":{"wkid":102100}},"attributes":{"symbolname":"Reference Point DLRP","z":null,"additionalinformation":null,"eny":null,"datetimevalid":null,"datetimeexpired":null,"distance":null,"azimuth":null,"uniquedesignation":null,"x":null,"y":null}} );
|
||||||
|
|
||||||
|
g_featureLayers[0]._validateFeature(testGraphic,g_featureLayers[0].url,"add")
|
||||||
|
.then(function(result){
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(testGraphic).toEqual(result.graphic);
|
||||||
|
expect(result.operation).toEqual("add");
|
||||||
|
done();
|
||||||
|
},function(error){
|
||||||
|
console.log("Validate feature error: " + error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async.it("validate existing feature - ADD", function(done){
|
||||||
|
var id = getObjectIds([g6]).toString();
|
||||||
|
expect(id).toEqual("-3");
|
||||||
|
g_featureLayers[0]._validateFeature(g6,g_featureLayers[0].url,"add")
|
||||||
|
.then(function(result){
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(g6).toEqual(result.graphic);
|
||||||
|
expect(JSON.stringify(g6.toJson()) === JSON.stringify(result.graphic.toJson())).toBeTruthy();
|
||||||
|
expect(result.operation).toEqual("add");
|
||||||
|
done();
|
||||||
|
},function(error){
|
||||||
|
console.log("Validate feature error: " + error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async.it("validate existing feature - UPDATE", function(done){
|
||||||
|
var id = getObjectIds([g6]).toString();
|
||||||
|
expect(id).toEqual("-3");
|
||||||
|
g_featureLayers[0]._validateFeature(g6,g_featureLayers[0].url,"update")
|
||||||
|
.then(function(result){
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(g6).toEqual(result.graphic);
|
||||||
|
|
||||||
|
// we swap the operation type when updating an edit that hasn't
|
||||||
|
// been submitted to the server yet.
|
||||||
|
expect(result.operation).toBe("add");
|
||||||
|
expect(JSON.stringify(g6.toJson()) === JSON.stringify(result.graphic.toJson())).toBeTruthy();
|
||||||
|
expect(result.operation).toEqual("add");
|
||||||
|
done();
|
||||||
|
},function(error){
|
||||||
|
console.log("Validate feature error: " + error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
async.it("check db size", function(done){
|
async.it("check db size", function(done){
|
||||||
g_featureLayers[0].getUsage(function(usage,error){
|
g_featureLayers[0].getUsage(function(usage,error){
|
||||||
expect(usage.sizeBytes).toBe(7978);
|
expect(usage.sizeBytes).toBe(7982);
|
||||||
expect(usage.editCount).toBe(9);
|
expect(usage.editCount).toBe(9);
|
||||||
expect(error).toBe(null);
|
expect(error).toBe(null);
|
||||||
done();
|
done();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user