Select to view content in your preferred language

Adding a row to a table using JS 4.x

3440
37
Jump to solution
11-20-2024 08:53 AM
Mr_Kirkwood
Regular Contributor

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. 

0 Kudos
4 Solutions

Accepted Solutions
JoelBennett
MVP Regular Contributor

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
            );
        });
    });
}

 

 

View solution in original post

JoelBennett
MVP Regular Contributor

To edit features, you would use:

featureLayer.applyEdits({updateFeatures:graphicsArr})

 

To delete features, you would use:

featureLayer.applyEdits({deleteFeatures:graphicsArr})

 

View solution in original post

JoelBennett
MVP Regular Contributor

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.

View solution in original post

JoelBennett
MVP Regular Contributor

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):

attributes.png

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.

 

View solution in original post

37 Replies
JoelBennett
MVP Regular Contributor

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
            );
        });
    });
}

 

Mr_Kirkwood
Regular Contributor

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! 

0 Kudos
JoelBennett
MVP Regular Contributor

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
            );
        });
    });
}

 

 

Mr_Kirkwood
Regular Contributor

Thank you! That works. I really appreciate your help.  

0 Kudos
Mr_Kirkwood
Regular Contributor

Joel,

If i want to delete or just edit do i change this line:

featureLayer.applyEdits({addFeatures:graphicsArr})

to deleteaFeatures and editFeatures?

 

 

0 Kudos
JoelBennett
MVP Regular Contributor

To edit features, you would use:

featureLayer.applyEdits({updateFeatures:graphicsArr})

 

To delete features, you would use:

featureLayer.applyEdits({deleteFeatures:graphicsArr})

 

Mr_Kirkwood
Regular Contributor

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

0 Kudos
Mr_Kirkwood
Regular Contributor

joel,

 

I got it to work. I was forgetting to grab the OBJECTID for the edit and delete. Thanks again! 

0 Kudos
Mr_Kirkwood
Regular Contributor

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 ()
    });
}
0 Kudos