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) {
|
||||
var deferred = new Deferred();
|
||||
|
||||
//self._validateFeature(addEdit).then(function(result){
|
||||
// console.log("HELLLLOOOO")
|
||||
//});
|
||||
|
||||
var objectId = this._getNextTempId();
|
||||
addEdit.attributes[this.objectIdField] = objectId;
|
||||
|
||||
var thisLayer = this;
|
||||
|
||||
self._editStore.pushEdit(self._editStore.ADD, this.url, addEdit, function (result, error) {
|
||||
if(result == true){
|
||||
results.addResults.push({success: true, error: null, objectId: objectId});
|
||||
// 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(addEdit,this.url,self._editStore.ADD).then(function(result){
|
||||
console.log("EDIT ADD IS BACK!!! " );
|
||||
|
||||
var phantomAdd = new Graphic(
|
||||
addEdit.geometry,
|
||||
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);
|
||||
if(result.success){
|
||||
thisLayer._pushValidatedAddFeatureToDB(thisLayer,addEdit,result.operation,results,objectId,deferred);
|
||||
}
|
||||
else{
|
||||
// If we can't push edit to database then we don't create a phantom graphic
|
||||
results.addResults.push({success: false, error: error, objectId: objectId});
|
||||
deferred.reject(error);
|
||||
// If we get here then we deleted an edit that was added offline.
|
||||
// We also have deleted the phantom graphic.
|
||||
deferred.resolve(true);
|
||||
}
|
||||
|
||||
},function(error){
|
||||
console.log("_validateFeature: Unable to validate!");
|
||||
deferred.reject(error);
|
||||
});
|
||||
|
||||
promises.push(deferred);
|
||||
@ -336,35 +320,24 @@ define([
|
||||
|
||||
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){
|
||||
results.updateResults.push({success: true, error: null, objectId: objectId});
|
||||
|
||||
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);
|
||||
if(result.success){
|
||||
thisLayer._pushValidatedUpdateFeatureToDB(thisLayer,updateEdit,result.operation,results,objectId,deferred);
|
||||
}
|
||||
else{
|
||||
// If we can't push edit to database then we don't create a phantom graphic
|
||||
results.addResults.push({success: false, error: error, objectId: objectId});
|
||||
deferred.reject(error);
|
||||
// If we get here then we deleted an edit that was added offline.
|
||||
// We also have deleted the phantom graphic.
|
||||
deferred.resolve(true);
|
||||
}
|
||||
|
||||
},function(error){
|
||||
console.log("_validateFeature: Unable to validate!");
|
||||
deferred.reject(error);
|
||||
});
|
||||
|
||||
promises.push(deferred);
|
||||
@ -642,6 +615,154 @@ define([
|
||||
|
||||
/* 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) {
|
||||
var files = [];
|
||||
var inputNodes = array.filter(formNode.elements, function (node) {
|
||||
@ -1316,52 +1437,6 @@ define([
|
||||
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
|
||||
* @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){
|
||||
g_featureLayers[0].getUsage(function(usage,error){
|
||||
expect(usage.sizeBytes).toBe(7978);
|
||||
expect(usage.sizeBytes).toBe(7982);
|
||||
expect(usage.editCount).toBe(9);
|
||||
expect(error).toBe(null);
|
||||
done();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user