Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGrid exportClientData() and ResultSet.getRange() improvement suggestions

    Hi Isomorphic,

    exportClientData() is a great feature, but has problems when not all data is loaded. I know that above a certain amount exportClientData() does not make a lot of sense because of loading times, rendering times and result-to-server-transfer times, but nowadays this threshold is certainly higher than 75 rows (the default dataPageSize).

    What would really help is an automatic download of the missing data, with warnings like "this is going to take some time" and a configurable threshold after that exportClientData() just does not work and requests the user to filter more, a bit like groupByMaxRecords.
    Otherwise the export can't be explained to end users. Why is it once 75 rows long, or 150 rows at other times?

    I have this code for this, that shows what I mean for the feature:
    Code:
    if (
                    // If grouped
                    (workLG.isGrouped() && workLG.getOriginalResultSet() != null && workLG.getOriginalResultSet().lengthIsKnown())
                            // If ungrouped
                            || (!workLG.isGrouped() && workLG.getResultSet() != null && workLG.getResultSet().lengthIsKnown())) {
                        ResultSet workRS = workLG.isGrouped() ? workLG.getOriginalResultSet() : workLG.getResultSet();
    
                        if (workRS.getLength() > 0) {
                            // Otherwise the export will not send a request and the SC.clearPrompt() call below will not be executed, effectively blocking the
                            // application
                            SC.showPrompt(I18nEdited.notification(), I18nEdited.exportStarted());
                        }
                        // Not all data is loaded clientside, so we load it with workRS.getRange(). In order to trigger the export directly after this
                        // (the method does not have a CallBack, which would make this more easy), DataArrivedHandler is used. This handler is removed
                        // again later in the CallBack of the exportListGrid.exportClientData() call.
                        if (!workRS.allMatchingRowsCached()) {
                            SC.logInfo(
                                    StringFormatter.format("Adding DataArrivedHandler to ResultSet {0} of ListGrid {1}", workRS.getID(), workLG.getID()));
                            // Will be removed afterwards again
                            loadAdditionalDataHandler = workRS.addDataArrivedHandler(new DataArrivedHandler() {
                                @Override
                                public void onDataArrived(DataArrivedEvent event) {
                                    exportClientData(workLG);
                                }
                            });
                            workRS.getRange(0, workRS.getLength());
                        } else {
                            exportClientData(workLG);
                        }
                    }
    
    
    
    private void exportClientData(ListGrid exportListGrid) {
                DSRequest exportRequest = getExportRequest(exportListGrid);
    
                SC.logInfo(StringFormatter.format("Starting exportClientData of ListGrid {0}", exportListGrid.getID()));
                exportListGrid.exportClientData(exportRequest, new RPCCallback() {
                    @Override
                    public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                        SC.clearPrompt();
                        if (loadAdditionalDataHandler != null) {
                            SC.logInfo(StringFormatter.format("Removing DataArrivedHandler of ListGrid {0} added previously", exportListGrid.getID()));
                            loadAdditionalDataHandler.removeHandler();
                            loadAdditionalDataHandler = null;
                        }
                        SC.logInfo(StringFormatter.format("exportClientData of ListGrid {0} finished", exportListGrid.getID()));
                    }
                });
            }
    The 2nd improvement suggestion is about ResultSet.getRange():
    As you can see, I have problems above with the asynchronous nature of getRange() combined with the fact that it doesn't have a CallBack. Having a CallBack would greatly simplify the code here (no DataArrivedHandler-add-and-remove-shenanigans).

    What do you think?

    Best regards
    Blama

    #2
    hi Blama ,

    We've added a new API, ListGrid.loadAllRecords([int maxRecords], [DSCallback callback]), which loads all data needed to fulfill the grid's current filter-criteria and fires the callback when the data arrives. If no fetch is needed, it fires the callback synchronously with null parameters.

    You can try it out in 12.1+ as of tomorrow's builds, dated November 8 or later.

    Comment


      #3
      Hi Isomorphic,

      thanks, I think this ListGrid.loadAllRecords() will help a lot, even more high-level than a method on ResultSet.
      I won't be using it now, but will make sure to note it in my ToDo-after-Update-document.

      What do you think of the exportClientData()-improvement idea? This would help developers even without having to write any code.

      Best regards
      Blama

      Comment


        #4
        At this point, if you want to do a client export with data preloading, you can just do roughly (pseudocode):

        Code:
            loadAllRecords(max, { exportClientData() });
        We might take it further in the future (e.g. providing error messages for too much data) if we add export options to the built-in menus. But that would require knowing that our server was present and that export was allowed, and would be senseless for many grids.

        Comment

        Working...
        X