Update DT based on success/fail logic is not yielding desired results

Update DT based on success/fail logic is not yielding desired results

pain19pain19 Posts: 57Questions: 5Answers: 0

Description of problem:
I use datatables a ton and they work extremely well for my needs. But I have recently run into an issue that I need help resolving after spending about (2) weeks trying to resolve on my own via the net and DT forums.

The pasted code does the following:
1. User is looking at a table of data and selects the rows that should be deleted.
2. The function below fires when the user confirms the action via the popup.
3. If API call is successful, then it will remove the corresponding row from the table.
4. If API fails, then the corresponding row should remain visible and be deselected.

What is happening:
* If all of the API calls are successful, all of the corresponding rows are deleted successfully.
* If all the API calls fail, all of the corresponding rows are deselected successfully.

The problem:
* If there a mix of success/fail, then the table gets screwed up (see below for details).

What happens with a Success/Fail Mix
Let's say there are (4) rows selected and what should happen is (2) successful API calls and (2) failures. What I want is for (2) rows to be deleted from the table and (2) rows remain visible, but are now de-selected. What is happening is (1) row that should be deleted is deleted from the table, but a row that should remain also disappears. And then the selection/de-selection is thrown off as well.

I have used console.log to ensure the code itself is functioning properly and it is. What I'm screwing up is manipulating the table. It's like I am changing the table in a way that it is losing track of the indexes for subsequent actions.

What I have tried:
* I have tried not manipulating the table during the API call, but rather pass the rows into arrays (ex. successArray and failedArray) and then manipulating the table that way so I know there's not a sync/async issue happening, but again the logging shows things are working correctly.
* I have tried success/error and then/catch (and then/catch/finally).
* Many different variations of the DT API calls and trying to control updating the table.
* And many other smaller coding techniques.

All have yielded the exact same results on the table, so I'm sure I am doing something I am not supposed to but can't seem to figure it out.

Any help is greatly appreciated it!!!! Thanks in advance!!!

function performDeletionWorkflowScheme (tableWorkflowSchemes) {
// First get confirmation from the user that this is what they actually want to do.
if (confirm("Are you sure you want to delete the selected row(s)?")) {
// Routine to delete the selected rows from the table. Iterates over each selected row.

    // Iterate through the selected rows.
    tableWorkflowSchemes.rows('.selected').every( function ( rowIdx, tableLoop, rowLoop) {

        //Declare the necessary variables to be passed in the request.
        var data = this.data();
        var workflowSchemeID = data['Workflow Scheme ID'];
        var workflowSchemeName = data['Workflow Scheme Name'];
        var deleteURL = "/rest/api/3/workflowscheme/";
        var finalUrl = "";

        // Strip all of the HTML away from the project key value we need to pass in the request.
        workflowSchemeID = workflowSchemeID.split('} -->').pop().split('<!-- /')[0];
        workflowSchemeName = workflowSchemeName.split('_blank">').pop().split('</a>')[0];

        // Construct the final format of the Url before passing it to the call.
        finalUrl = deleteURL + workflowSchemeID;

        // Make the APU call to attempt to delete the current selected row.
        deleteData(finalUrl, 'DELETE', '')
        .then(function(responseText) {

            // Make the DT call to remove the row from the table.
            tableWorkflowSchemes.row('.selected').remove().draw(false);

            // Call the function to update the displayed row count.
            postDeletionWorkflowSchemeTotalAudit(tableWorkflowSchemes);

        }).catch(function(err) {

            // Could not be deleted, so keep the row but deselect it.
            tableWorkflowSchemes.row( {selected: true } ).deselect();

            // Grab the error message and display to the user in an alert/
            var errorStatus = err.status;
            var errorMessage = err.responseText;

            // Grab the actual message and remove the surrounding noise.
            errorMessage = errorMessage.split(':[\"').pop().split('\"],')[0];

            // Popup the alert.
            //alert("Error: " + errorStatus + ": " + errorMessage + "\n\nWorkflow Scheme Name: " + workflowSchemeName);
        });
    });
}

}

Replies

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    For CRUD operations, it would be worth looking at Editor, as it's designed to solve these kind of problems,

    Colin

  • pain19pain19 Posts: 57Questions: 5Answers: 0

    Colin,

    Thanks for the reference. After reviewing the link and docs, I think this might be overkill for what I need at this time as my users/admins will not be editing any data of the rows.

    My app is a plugin to a larger tool. It is designed to pull data into a central location for the tool admins so they don't have to click all over the place to get the same data.

    My use case is this:

    Let's say the main tool has (100) projects. My app calls the tool's API and retrieves those projects and displays them in the datatable. The admin decides (10) of the projects should be deleted.

    If the API call deletes all (10) projects successfully, then my datatable successfully removes the rows and displays correctly. If the API call fails to delete all (10) projects, then my datatable successfully de-selects the rows and again, displays correctly.

    Where the problem comes in is if I need to remove (5) rows and de-select the other (5) for some combination of success/fail. I get mixed results in my datatable, but none are correct. It just seems like I cannot manipulate the table during the API calls as it changes the table in a way that the indexes of the rows gets messed up--which makes sense.

    I think doing the datatable work during the API work is not working because it is removing rows and thus, changing the table so the de-select and removes jumps around--which also makes sense.

    So, what I am currently trying is to do all of the API work first. If success, put those in a successArray and if it fails, put those in a failedArray. Then once all of the API work is done, I want to iterate over the arrays. I think doing the failedArray first and de-selecting will work as the de-select process doesn't change the number of rows or indexes that I need to work with. Then I'll iterate over the successArray and remove those rows.

    I'll keep working and if I get it to work, I will report back in case others could use it.

    While I haven't posted a lot here, please know that I absolutely "love" DataTables and it has been a HUGE time saver for what I've been doing!

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Glad DataTables has been useful for you, that feedback is always good to hear! Good luck with the coding.

    Colin

  • pain19pain19 Posts: 57Questions: 5Answers: 0

    Quick update in case others need this tip.

    My issue was that I was using row('.selected') instead of row(this)---making sure I was operating on the "current" row.

This discussion has been closed.