Announcement

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

    TreeGrid refreshData and selectionProperty errors

    When using Treegrid, I noticed that 3 errors appear

    1. If I select a child node of one of the main nodes and then call refreshData(), then the main node itself and all its child nodes are selected

    2. If I filter the tree through FilterBar and call refresh Data(), then after it is executed, the tree filtering is reset and the tree shows all nodes

    3. If I use selectionProperty="state" on the tree, a warning appears in the debugger console
    "ISC_Core.js:1432*08:59:19.958:MMV0:WARN:TreeGridBody:multilanguageList_body:row heights not yet available; returning all zeroes"
    and TreeGrid_Body does not respond


    I have prepared code for testing where these errors can be reproduced.
    Code:
    import React, { Component } from 'react';
    import { DataSource, DSField, VLayout, Button, TreeGrid, TGField } from 'smartclient-pro/react';
    class App extends Component {
      constructor(param) {
        super(param);
      };
      transformMultilanguages(dsResponse, dsRequest, data) {
        this.setupIDs(dsResponse.data, 1);
        return dsResponse;
      }
      setupIDs(records, id, pid) {
        let $id = id;
        for (let record of records) {
          record.parentId = pid;
          record.id = $id;
          $id++;
          let childs = record.properties;
          if (childs != null && childs.length) {
            $id = this.setupIDs(childs, $id, $id - 1);
          }
        }
        return $id;
      }
      onSelectionUpdated(firstRecord, selectedRecords) {
        let grid = window.multilanguageList;
        let tree = grid.data;
        for (let record of selectedRecords) {
          record.changed = true;
          let parents = tree.getParents(record);
          for (let parent of parents) {
            parent.changed = true;
          }
        }
      }
      refreshData() {
        window.multilanguageList.refreshData();
      }
      render() {
        return (
          <>
            <DataSource ID="multilanguageDS" clientOnly="true"
              dataURL="multilanguageStates.txt"
              transformResponse={this.transformMultilanguages.bind(this)}
            >
              <fields>
                <DSField name="id" type="integer" primaryKey="true" />
                <DSField name="parentId" type="integer" foreignKey="id" />
                <DSField name="name" type="text" canFilter="true" />
                <DSField name="state" type="boolean" />
                <DSField name="istate" type="boolean" />
                <DSField name="checkedState" type="integer" />
                <DSField name="changed" type="boolean" />
                <DSField name="properties" type="any" childrenProperty="true" />
              </fields>
            </DataSource>
            <VLayout membersMargin="5" width="100%" height="100%">
              <members>
                <Button
                  title="refresh data"
                  autoFit="true" showFocused="false"
                  click={this.refreshData.bind(this)}
                />
                <TreeGrid ID="multilanguageList" dataSource="multilanguageDS" autoFetchData="true" loadDataOnDemand="false" keepParentsOnFilter="true" filterOnKeypress="true"
                  width="100%" height="*" canEdit="false" showFilterEditor="true" showHeader="false" showFolderIcons="false" showNodeIcons="false"
                  selectionUpdated={this.onSelectionUpdated.bind(this)} selectionAppearance="checkbox" showSelectedStyle="false" cascadeSelection="true" showPartialSelection="true"
                >
                  <fields>
                    <TGField name="name" escapeHTML="false" />
                  </fields>
                </TreeGrid>
              </members>
            </VLayout>
          </>
        );
      }
    }
    export default App;
    /*
                  selectionProperty="state"
    */
    File to download in DataSource
    multilanguageStates.txt

    #2
    #1 - we think this is a bug and we know what it is, we'll look at it

    #2 - refreshData() will cause a DSRequest with criteria to be send to your DataSource. Because of your combination of a static text file and a transformResponse() override, your DataSource does not support filtering. Note that filtering was only working up to this point because it was being done inside the TreeGrid, because the loaded data was complete.

    One approach to fix this would be to declare your DataSource as not being clientOnly, but then set cacheAllData:true.

    #3 - your setting here is clobbering other metadata stored on treeNodes. You should be able to shift to a different property name - please confirm that this works. Meanwhile, we'll check which metadata you are clobbering and see if we can make it renamable (as is already the case for e.g. tree.openProperty.

    Comment


      #3
      #2 - refreshData() will cause a DSRequest with criteria to be send to your DataSource. Because of your combination of a static text file and a transformResponse() override, your DataSource does not support filtering. Note that filtering was only working up to this point because it was being done inside the TreeGrid, because the loaded data was complete.

      One approach to fix this would be to declare your DataSource as not being clientOnly, but then set cacheAllData:true.
      unfortunately, this does not work. I changed my code to this one
      Code:
              <DataSource ID="multilanguageDS" clientOnly="false" cacheAllData="true"
                dataURL="multilanguageStates.txt"
                transformResponse={this.transformMultilanguages.bind(this)}
              >
      and an error appeared in the debugger console
      Code:
      TypeError: Cannot create property 'parentId' on string 'T'
          at App.setupIDs (App.js:18:1)
          at App.transformMultilanguages (App.js:11:1)
          at _3.transformResponse (ISC_DataBinding.js:915:13)
          at _3.isc_DataSource__completeResponseProcessing [as $38b] (ISC_DataBinding.js:631:13)
          at _3.isc_DataSource__handleSCServerReply [as $50h] (ISC_DataBinding.js:2881:6)
          at _3.isc_c_Class_fireCallback [as fireCallback] (ISC_Core.js:328:252)
          at _3.isc_Class_fireCallback [as fireCallback] (ISC_Core.js:422:302)
          at _3.isc_c_RPCManager_fireReplyCallback [as fireReplyCallback] (ISC_DataBinding.js:1720:309)
          at _3.isc_c_RPCManager_fireReplyCallbacks [as fireReplyCallbacks] (ISC_DataBinding.js:1723:120)
          at _3.isc_c_RPCManager_completeOperationReply [as completeOperationReply] (ISC_DataBinding.js:1714:6)
          at _3.isc_c_RPCManager_performOperationReply [as performOperationReply] (ISC_DataBinding.js:1712:109)
          at _3.isc_c_RPCManager__performTransactionReply [as $39d] (ISC_DataBinding.js:1641:26)
          at _3.isc_c_RPCManager_performTransactionReply [as performTransactionReply] (ISC_DataBinding.js:1599:20)
          at eval (eval at isc__makeFunction (ISC_Core.js:90:1135), <anonymous>:3:16)
          at _3.isc_c_Class_fireCallback [as fireCallback] (ISC_Core.js:328:252)
          at _3.isc_c_Comm_performXmlTransactionReply [as performXmlTransactionReply] (ISC_Core.js:2268:27)
          at eval (eval at isc__makeFunction (ISC_Core.js:90:1135), <anonymous>:3:10)
          at Object.isc_c_Class_fireCallback [as fireCallback] (ISC_Core.js:328:252)
          at _3.isc_c_Comm__fireXMLCallback [as $h0] (ISC_Core.js:2243:451)
          at XMLHttpRequest._15 (ISC_Core.js:2252:135)

      #3 - your setting here is clobbering other metadata stored on treeNodes. You should be able to shift to a different property name - please confirm that this works. Meanwhile, we'll check which metadata you are clobbering and see if we can make it renamable (as is already the case for e.g. tree.openProperty.
      I tried using "istate" instead of the "state" property and the result is the same

      Comment


        #4
        #1 that's your transformRequest() method at the top of the stack that's crashing - this looks to be because "properties" is ending up as just a String, because it's declared as type "any", whereas it should actually be declared as the type of your DataSource ("multilanguageDS") since it's a nested record.

        Note this has changed in this mode because with clientOnly mode we basically try to "guess" what's in the data file and don't try to process it, but in the normal mode, we actually take your DataSource settings and validate the data (make everything the correct type, etc).

        #3 we are seeing that using basically any other property name works. Can you please retest and make sure?

        Comment


          #5
          #1 that's your transformRequest() method at the top of the stack that's crashing - this looks to be because "properties" is ending up as just a String, because it's declared as type "any", whereas it should actually be declared as the type of your DataSource ("multilanguageDS") since it's a nested record.

          Note this has changed in this mode because with clientOnly mode we basically try to "guess" what's in the data file and don't try to process it, but in the normal mode, we actually take your DataSource settings and validate the data (make everything the correct type, etc).
          I removed type="any" in DataSourceField, but the error still appears

          #3 we are seeing that using basically any other property name works. Can you please retest and make sure?
          I noticed one pattern... If I have the "state" property set to false in all DataSource records, then the error does not appear and everything works correctly. But if I set state=true in at least one record before creating a TreeGrid, then the error I described appears.
          the same thing happens if I take the abcd property instead of the state property
          Last edited by Hirn; 28 Apr 2024, 11:43.

          Comment


            #6
            On #1, again, it's your code crashing. You should dump the data (isc.echoAll() is a good helper here) and take a look. Most likely, you need to set dataFormat:"json" and possibly recordXPath, or reformat the data to match the expectations documented for this mode. It's likely to be as simple as an Array wrapper around the single element from your JSON, because this mode expects the server to provide an Array of Records.

            On #3, if you're using the name "state", we would expect a crash. Whether it crashes differently based on the values in the state field is just a curiosity. Can you confirm that there is no problem if you use a property name other than "state"? Because that's what we're seeing.

            Comment


              #7
              Actually, hang on: on #3 it looks like you are actually trying to set the initial selected state. Is that true?

              Edit: we'll assume this was your intended usage. Because you were showing a text file, we were assuming that you just happened to collide with internal metadata rather than that you were actually trying to control the initial selection. But we are thinking now that the text file was just to make a runnable test case!
              Last edited by Isomorphic; 29 Apr 2024, 18:30.

              Comment


                #8
                Yes. My idea was to initialize the selection in treegrid using the state property. I used the "abcd" property instead of the "state" property and the error still appeared.
                I noticed another manifestation of the error, but now not during initial initialization, but after updating the tree. I, with a filtered tree, retain the "abcd" property in the original data, and after resetting the filtering, the same error appears.

                Comment


                  #9
                  We've made fixes to SC back to the 12.1 branch to address the refreshData() selection problem you pointed out, and a separate issue with the TreeGrid not responding after first draw. These should be in the nightly builds dated 2024-05-14 and beyond.

                  Comment

                  Working...
                  X