State Restore's new save/rename/remove callback is only working for save when using server side post

State Restore's new save/rename/remove callback is only working for save when using server side post

desperadodesperado Posts: 159Questions: 33Answers: 4
edited January 2022 in StateRestore

I am testing StateRestore 1.1.0 and Buttons 2.2.1 and have found a problem when using ajax state restore.

Here is my test case. I flipped the logic from done to fail because I couldn't think of a way to get post to succeed without my actual server.

http://live.datatables.net/cixelute/1/edit?js,console,output

Test Scenario
You can see that each time my stateRestoreAjax method is called it attempts a post and on failure (make believe it was "done" success) it calls the callback();
If you test save updates the dropdown list with the new "State 1" but attempt to remove or rename "State 1" will no be reflected correctly in the dropdown.

Test scenario
1) Select "Saved States->Create State"
2) Save "State 1"
3) Note the dropdown get correctly updated with "State 1"
4) Now try to rename or remove "State 1", the callback is called correctly (seen in console) but the dropdown is not updated.

Sorry if moving the "callback()" to fail is confusing but that was the only way I could get a simple test case to demonstrate the issue. My actual code looks more like this. See the comments starting with // ************** for my findings while testing

            function stateRestoreAjax(data, callback) {
                // Action to take if loading states
                if (data.action === 'load') {
                    let url = _rcoiBaseUrl + "dataTablesView/getViews/" + _dataTableViewStoreDataTableId;
                    $.get(url, function (data, status) {
                        let cbData = {};
                        for (let i = 0; i < data.length; i++) {
                            // Convert back from the string created when saving
                            cbData[data[i].identifier] = JSON.parse(data[i].state);
                        }
                        // Load states into StateRestore
                        console.log("starting callback");
                        _stateRestoreBlockSaveAjaxCall = true;
                        callback(cbData);
                        _stateRestoreBlockSaveAjaxCall = false;
                        console.log("Finished callback")
                    });
                }
                // Action to take if renaming states
                else if (data.action === 'rename') {
                    if (_stateRestoreBlockRenameAjaxCall) {
                        return;
                    }
                    // Get all of the state identifiers
                    var ids = Object.keys(data.stateRestore);
                    for (var i = 0; i < ids.length; i++) {
                        let url = _rcoiBaseUrl + "dataTablesView/renameView";
                        let viewId = ids[i];
                        let newViewId = data.stateRestore[ids[i]];
                        let _viewSaveRequestData = {
                            'viewId': viewId,
                            'newViewId': newViewId,
                            'dataTableId': _dataTableViewStoreDataTableId
                        };
                        // This allows the post to pass the security token verification
                        // without this data you will get a 401 error
                        _viewSaveRequestData[_dt_sr_csrf_param_name] = _dt_sr_csrf_token; // Adds the token
                        console.log("Renaming");
                        $.post(url, _viewSaveRequestData).done(function () {
                            console.log("Rename View done, issuing callback");
                            callback();  // ********** THIS CALLBACK NOT WORKING *****************
                        }).fail(function () {
                            console.log("Rename Request Failed");
                            // Remove the state true prevents modal confirmation
                            alert("Sorry, rename view:'" + viewId + "' to '" + newViewId + "' failed, contact help desk if this condition persists.")
                        });
                    }
                }
                // Action to take if removing states
                else if (data.action === 'remove') {
                    if (_stateRestoreBlockRemoveAjaxCall) {
                        return;
                    }
                    var ids = Object.keys(data.stateRestore);
                    for (var i = 0; i < ids.length; i++) {
                        let url = _rcoiBaseUrl + "dataTablesView/removeView";
                        let viewId = ids[i];
                        let viewData = data.stateRestore[ids[i]];
                        let _viewSaveRequestData = {
                            'viewId': viewId,
                            'dataTableId': _dataTableViewStoreDataTableId
                        };
                        // This allows the post to pass the security token verification
                        // without this data you will get a 401 error
                        _viewSaveRequestData[_dt_sr_csrf_param_name] = _dt_sr_csrf_token; // Adds the token
                        console.log("Removing " + viewId);
                        // callback();  // ******* CALLBACK HERE WORKS BUT THEN GETS CALLED EVEN ON FAIL
                        $.post(url, _viewSaveRequestData).done(function () {
                            console.log("Remove View done, issuing callback");
                            callback();  // ********** THIS CALLBACK NOT WORKING *****************
                        }).fail(function () {
                            console.log("Remove Request Failed");
                            alert("Sorry, view:'" + viewId + "' failed to remove, contact help desk if this condition persists.")
                        });
                    }
                }
                // Action to take if saving states
                else if (data.action === 'save') {
                    let ids = Object.keys(data.stateRestore);
                    if (_stateRestoreBlockSaveAjaxCall) {
                        // Fix issue with stateRestore calling save for every State when loading
                        console.log("Blocked Save on Load from State Restore");
                        callback();
                        return;
                    }
                    for (let i = 0; i < ids.length; i++) {
                        let url = _rcoiBaseUrl + "dataTablesView/saveView";
                        let viewId = ids[i];
                        let viewData = JSON.stringify(data.stateRestore[ids[i]]);
                        let _viewSaveRequestData = {
                            'viewId': viewId,
                            'viewData': viewData,
                            'dataTableId': _dataTableViewStoreDataTableId
                        };
                        // This allows the post to pass the security token verification
                        // without this data you will get a 401 error
                        _viewSaveRequestData[_dt_sr_csrf_param_name] = _dt_sr_csrf_token; // Adds the token
                        console.log("Saving");
                        $.post(url, _viewSaveRequestData).done(function () {
                            console.log("Save View done, issuing callback");
                            callback();  // ******************* ONLY THIS CALL BACK FOR SAVE WORKS *******************/
                        }).fail(function () {
                            console.log("Save Request Failed");
                            alert("Sorry, view:'" + viewId + "' failed to save, contact help desk if this condition persists.")
                        });
                    }
                }
            }

Answers

  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @desperado ,

    Thanks for pointing this out. I'm pretty sure this is going to be an issue with the async timing - basically I'm going to move more code into the callback which is ok. I've raised an issue internally (DD-2436 for my reference) and will report back here when there is an update.

    Thanks,
    Sandy

  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @desperado ,

    That should be the issue fixed now. This will be available in the next StateRestore release which we hope will be in the next few weeks. Until then you can access the fix from the nightly builds.

    Thanks,
    Sandy

  • desperadodesperado Posts: 159Questions: 33Answers: 4

    @sandy Thanks, nightly version working in my system.

Sign In or Register to comment.