I was using JS 3.x to add and update data. I am working on convert my applications to JS 4.x. I had a script that used "dojo/Deferred". Here is the code:
function _applyAdds (featureLayer, propertiesArr)
{
var defer;
require (['esri/graphic', "dojo/Deferred"], function (Graphic, Deferred)
{
defer = new Deferred ();
var graphicsArr = [];
propertiesArr.forEach (function (properties)
{
graphicsArr.push (new Graphic (null, null, properties));
});
featureLayer.applyEdits (
graphicsArr, null, null,
function (a, u, d)
{
console.log (a, u, d);
defer.resolve ();
}, // callback
function (error)
{
console.log ('ERROR!', error);
}// errorback
);
});
return defer.promise;
}
//begin adding new employee assignment
function assignEmployee ()
{
var addEmployee = {};
addEmployee.SPACEKEY = document.getElementById ('EmployeeSpaceID').value;
addEmployee.EMPLOYEEKEY = document.getElementById ('EmployeeID').value;
console.log (addEmployee);
_applyAdds (roomAssinmentTable, [addEmployee]).then (function ()
{
console.log ("Add Employee");
});
}
How do i make this work in JS 4.x?
Thank you in advance for any help on this.
Solved! Go to Solution.
I thought you were asking specifically about the replacement for dojo's Deferred module. To migrate the whole function, you'll also need to update the use of FeatureLayer and Graphic for compatibility with 4.x:
function _applyAdds (featureLayer, propertiesArr)
{
return new Promise(function(resolve, reject) {
require (['esri/Graphic'], function (Graphic)
{
var graphicsArr = [];
propertiesArr.forEach (function (properties)
{
graphicsArr.push (new Graphic ({attributes:properties}));
});
featureLayer.applyEdits({addFeatures:graphicsArr}).then(
function (results)
{
console.log (results);
resolve();
}, // callback
function (error)
{
console.log ('ERROR!', error);
reject(error);
}// errorback
);
});
});
}
To edit features, you would use:
featureLayer.applyEdits({updateFeatures:graphicsArr})
To delete features, you would use:
featureLayer.applyEdits({deleteFeatures:graphicsArr})
It looks like "roomEditData" is an array of objectIDs. In that case, you'd want something like this instead of what you presently have on lines 4-10:
const updates = [];
roomEditData.forEach(function(oid) {
updates.push ({
attributes: {
OBJECTID: oid,
PHYSICALCAPACITY: document.getElementById ('editroomDetails-PHYSICALCAPACITY').value
}
});
});
That assumes that the OID field name for the layer is actually "OBJECTID". If it isn't, you'll need to change the field name on line 5.
Hmm...well, not sure what's going on, but here's a few things to look into:
1) Determine the format of date values passed between your server and the client, so you can determine the value to post back during edits. To do so, use your browser's developer tools to look at the contents of a query to the same layer, and look at the date value for a returned record. Make sure your edit request uses the same type of value (here we see this example using the numeric format I mentioned earlier):
2) Make sure you're using the correct field name. Note that field names are case sensitive.
3) Make sure it's not a read-only field. For example, if you look at the information for this service used by one of the editing samples, you'll see many of the entries in the "Fields" section have an "editable" value of false.
4) If you have access to ArcGIS Server Manager, log in and check the logs for the service and time frame of your edits for any error messages.
You should use the native Promise object instead. Here is what the above code would look like using it:
function _applyAdds (featureLayer, propertiesArr)
{
return new Promise(function(resolve, reject) {
require (['esri/graphic'], function (Graphic)
{
var graphicsArr = [];
propertiesArr.forEach (function (properties)
{
graphicsArr.push (new Graphic (null, null, properties));
});
featureLayer.applyEdits (
graphicsArr, null, null,
function (a, u, d)
{
console.log (a, u, d);
resolve();
}, // callback
function (error)
{
console.log ('ERROR!', error);
reject(error);
}// errorback
);
});
});
}
Thank you, Joel, for helping. I am now getting this error message:
4.30/:31 Error: scriptError: https://js.arcgis.com/4.30/esri/graphic.js
src: dojoLoader
info: (2) ['https://js.arcgis.com/4.30/esri/graphic.js', Event]
Thanks in advance!
I thought you were asking specifically about the replacement for dojo's Deferred module. To migrate the whole function, you'll also need to update the use of FeatureLayer and Graphic for compatibility with 4.x:
function _applyAdds (featureLayer, propertiesArr)
{
return new Promise(function(resolve, reject) {
require (['esri/Graphic'], function (Graphic)
{
var graphicsArr = [];
propertiesArr.forEach (function (properties)
{
graphicsArr.push (new Graphic ({attributes:properties}));
});
featureLayer.applyEdits({addFeatures:graphicsArr}).then(
function (results)
{
console.log (results);
resolve();
}, // callback
function (error)
{
console.log ('ERROR!', error);
reject(error);
}// errorback
);
});
});
}
Thank you! That works. I really appreciate your help.
Joel,
If i want to delete or just edit do i change this line:
featureLayer.applyEdits({addFeatures:graphicsArr})to deleteaFeatures and editFeatures?
To edit features, you would use:
featureLayer.applyEdits({updateFeatures:graphicsArr})
To delete features, you would use:
featureLayer.applyEdits({deleteFeatures:graphicsArr})
That is what i thought. i had been trying it but was getting this error:
ERROR! e {name: 'request:server', details: {…}, message: 'Unable to complete operation.'}details: getAllHeaders: ()=>Array.from(Z.headers)getHeader: ra=>Z.headers.get(ra)httpStatus: 500messageCode: undefinedmessages: ["No edits ('adds', 'updates', 'deletes', 'attachment edits', or 'asset maps edits') were specified."]raw: {code: 500, message: 'Unable to complete operation.', details: Array(1)}requestOptions: {method: 'post', query: {…}, responseType: 'json'}ssl: truesubCode: undefinedurl: "https://uwoperations.uwyo.edu/hostgis/rest/services/REO/REV_UWOPS_EditRooms/FeatureServer/1/applyEdi..."[[Prototype]]: Objectmessage: "Unable to complete operation."name: "request:server"[[Prototype]]: ctype: "error"constructor: class etoJSON: toJSON(){if(null!=this.details)try{return{name:this.name, message:this.message,details:JSON.parse(JSON.stringify(this.details,(d,p)=> {…}[[Prototype]]: Object
joel,
I got it to work. I was forgetting to grab the OBJECTID for the edit and delete. Thanks again!
How would i be able to pass multiple OBJECTIDS to edit in batch with the code above?
here is what i am using to grab information from a popup window:
function editRoomData ()
{
roomObjectID = attributes.OBJECTID
console.log (roomObjectID);
var editRoom = {};
editRoom.OBJECTID = Number (roomObjectID)
editRoom.ADA = document.getElementById ('roomDetails-ADA').value;
editRoom.CAPACITY = document.getElementById ('roomDetails-CAPACITY').value;
editRoom.SPACETYPECAT1KEY = document.getElementById ('roomDetails-SPACETYPECAT1KEY').value;
editRoom.SPACETYPECAT2KEY = document.getElementById ('roomDetails-SPACETYPECAT2KEY').value;
editRoom.SPACEUSECAT1KEY = document.getElementById ('roomDetails-SPACEUSECAT1KEY').value;
editRoom.SPACEUSECAT2KEY = document.getElementById ('roomDetails-SPACEUSECAT2KEY').value;
editRoom.DESCRIPTION = document.getElementById ('roomDetails-DESCRIPTION').value;
editRoom.CAPACITY = document.getElementById ('roomDetails-CAPACITY').value;
editRoom.ASSIGNABLE = document.getElementById ('roomDetails-ASSIGNABLE').value;
editRoom.NOTES = document.getElementById ('roomDetails-NOTES').value;
editRoom.USABLE = document.getElementById ('roomDetails-USABLE').value;
_applyEdits (roomsTable, [editRoom]).then (function ()
{
$ ('#customWindow').jqxWindow ('close');
$ ('#typeUseCategoryWindow').jqxWindow ('close');
view.popup.close ()
});
}