Announcement

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

    ListGrid error on remove

    Hi,
    I have a ListGrid with deferred removal that shows data from a DataSource filtered by a field. When I attempt to perform a remove operation, I always get a JavaScript error when saving changes.

    You can reproduce it by using the following code snippet:
    Code:
    isc.RestDataSource.create({
        ID: "ds",
        fields: [
            {name: "pk", type: "sequence", primaryKey: true, hidden: true},
            {name: "fk", type: "sequence"},
            {name: "value", type: "sequence"}
        ],
        clientOnly: true,
        cacheData: [
            {pk: 1, fk: 1, value: 1},
            {pk: 2, fk: 1, value: 2},
            {pk: 3, fk: 2, value: 3},
            {pk: 4, fk: 2, value: 4}
        ]
    });
    
    isc.Button.create({
        ID: "saveBtn",
        title: "save",
        action: function() {
            list.saveAllEdits();
        }
    });
    
    isc.ListGrid.create({
        ID: "list",
        canRemoveRecords: true,
        deferRemoval: true,
        dataSource: ds,
    });
    list.fetchData({fk: 1});
    
    isc.VLayout.create({
        ID: "testLayout",
        members: [
            saveBtn,
            list
        ]
    });
    Steps to reproduce:
    1- Mark for removal the two records in the ListGrid.
    2- Confirm your removal by clicking the save button.
    3- You will see that only one record gets removed, and find a JavaScript error in your browser console.

    JavaScript error stack trace:
    Code:
    *17:16:35.472:TMR2:WARN:Log:TypeError: Cannot read property '0' of undefined
    Stack from error.stack:
        get(<no args: exited>) on [ResultSet ID:isc_ResultSet_3 (dataSource: ds, created by: list)] @ ISC_DataBinding.js.jsf:45939:37
        discardEdits(<no args: exited>) on[ListGrid ID:list] @ ISC_Grids.js.jsf:53534:45
        removeDataComplete(<no args: exited>) on[ListGrid ID:list] @ ISC_Grids.js.jsf:55977:22
        fireCallback(callback=>Obj, argNames=>"dsResponse,data,dsRequest", args=>Array[3], target=>[ListGrid ID:list], catchErrors=>undef) on [Class RestDataSource] @ ISC_Core.js.jsf:6805:36
        fireCallback(callback=>Obj, argNames=>"dsResponse,data,dsRequest", args=>Array[3], catchErrors=>undef) on [RestDataSource ID:ds] @ ISC_Core.js.jsf:8653:32
        fireResponseCallbacks(dsResponse=>Obj, dsRequest=>Obj, rpcResponse=>Obj, rpcRequest=>Obj) on [RestDataSource ID:ds] @ ISC_DataBinding.js.jsf:18784:39
        _completeResponseProcessing(data=>Obj, dsResponse=>Obj, dsRequest=>Obj, rpcResponse=>Obj, rpcRequest=>Obj) on [RestDataSource ID:ds] @ ISC_DataBinding.js.jsf:18735:14
        callback(dsResponse=>Obj) on [RestDataSource ID:ds] @ ISC_DataBinding.js.jsf:16510:18
        _handleClientOnlyReply(rpcResponse=>Obj, data=>Obj, rpcRequest=>Obj) on [RestDataSource ID:ds] @ ISC_DataBinding.js.jsf:16518:22
        fireCallback(<no args: recursion>)  on [Class RPCManager] @ ISC_Core.js.jsf:6805:36
        fireCallback(<no args: recursion>)  on [RPCManager ID:builtinApplication] @ ISC_Core.js.jsf:8653:32
        fireReplyCallback(callback=>Obj, request=>Obj, response=>Obj, data=>Obj) on [Class RPCManager] @ ISC_DataBinding.js.jsf:41245:42
        fireReplyCallbacks(request=>Obj, response=>Obj) on [Class RPCManager] @ ISC_DataBinding.js.jsf:41308:18
        performOperationReply(request=>Obj, response=>Obj) on [Class RPCManager] @ ISC_DataBinding.js.jsf:41237:21
        _performTransactionReply(transactionNum=>20) on [Class RPCManager] @ ISC_DataBinding.js.jsf:41151:18
        fireCallback(<no args: recursion>)  on [Class Timer] @ ISC_Core.js.jsf:6805:36
        _fireTimeout(ID=>"_timeout180", tmrID=>435, delayedTmrID=>undef) on [Class Timer] @ ISC_Core.js.jsf:33271:10
        <anonymous>() @ ISC_Core.js.jsf:33193:19
    Browser: Google Chrome 47.0.2526.111 m
    SmartClient version: v10.1p_2016-01-21

    #2
    A RestDataSource that is marked clientOnly is a nonsense combination, this is one of many errors that might result from this combination of settings.

    Comment


      #3
      Hi,
      I am using clientOnly RestDataSource to avoid client/server communication in this snippet, but in my application I actually use communication with the server and get exactly the same JavaScript exception. Futhermore, if you replace the RestDataSource by a DataSource, you will still get this error.

      Comment


        #4
        We are not reproducing a problem when we work with valid code. Starting with this sample of a RestDataSource

        http://www.smartclient.com/#restEditSave

        We added canRemoveRecords:true, deferRemoval:true to the grid, and changes one of the buttons to call saveAllEdits().

        This worked as expected - a request representing a transactional queue with two "remove" DSRequests is sent to the server. The sample then crashes while trying to process the response, which is expected, since this sample has hardcoded responses.

        The stack trace you showed is meaningless because it's from the combination of RestDataSource with clientOnly, but the error you are experiencing in your (presumably valid) real code may just be because your server is not responding with the expected format for transactional queued requests. See the docs for RestDataSource for the formats used for sending and receiving queued requests.

        Comment


          #5
          Hi,
          After some modifications in http://www.smartclient.com/#restEditSave I've been able to reproduce the problem I'm having.
          In order to reproduce it, you need to use a criteria when doing the fetch. This is why I added an initialCriteria attribute. Furthermore, I've chosen a criteria that is satisfied by all the countries in the dataset, so that we do not have any incoherence between the criteria and the fetch response. For the same reason, in my test I only remove the "UK" record which is the only hardcoded remove response.

          The code is as follows:
          Code:
          isc.RestDataSource.create({
              ID:"countryDS",
              fields:[
                  {name:"countryCode", title:"Code", primaryKey:true, canEdit:false},
                  {name:"countryName", title:"Country"},
                  {name:"capital", title:"Capital"}
              ],
              
              fetchDataURL:"[ISOMORPHIC]/system/reference/inlineExamples/dataIntegration/xml/responses/country_fetch_rest.xml",
              addDataURL:"[ISOMORPHIC]/system/reference/inlineExamples/dataIntegration/xml/responses/country_add_rest.xml",
              updateDataURL:"[ISOMORPHIC]/system/reference/inlineExamples/dataIntegration/xml/responses/country_update_rest.xml",
              removeDataURL:"[ISOMORPHIC]/system/reference/inlineExamples/dataIntegration/xml/responses/country_remove_rest.xml"
              
                  
          });
            
          isc.ListGrid.create({
              ID: "countryList",
              width:500, height:224, alternateRecordStyles:true,
              emptyCellValue: "--",
              dataSource: countryDS,
          initialCriteria: { // Added by me
                  _constructor:"AdvancedCriteria",
                  operator:"and",
                  criteria:[
                      { fieldName:"continent", operator:"iContains", value:"e"}
                  ]
          },
          canRemoveRecords: true, // Added by me
          deferRemoval: true, // Added by me
              // display a subset of fields from the datasource
              fields:[
                  {name:"countryCode"},
                  {name:"countryName"},
                  {name:"capital"},
                  {name:"continent"}
              ],
              sortFieldNum: 0, // sort by countryCode
              dataPageSize: 50,
              autoFetchData:true
          });
          
          isc.HLayout.create({
              membersMargin:15,
              top:240,
              members: [
                  isc.IButton.create({
                      width:150,
                      title:"Add new country",
                      click: function () {
          countryList.saveAllEdits(); // Added by me
                      }
                  }),
                  isc.IButton.create({
                      width:150,
                      title:"Update country (US)",
              
                      click: function () {
                          countryList.updateData(
                              {
                                  countryCode: "US",
                                  countryName:"Edited Value",
                                  capital:"Edited Value",
                                  continent:"Edited Value"
                              }
                          );
                  
                          countryList.selection.selectSingle({countryCode:"US"})
                          this.disable();
                      }
                  }),
                  isc.IButton.create({
                      width:150,
                      title:"Remove country (UK)",
              
                      click: function () {
                          countryList.removeData(
                              {
                                  countryCode: "UK"
                              }
                          );
                          this.disable();
                      }
                  })
              ]
          });
          Steps to reproduce:
          1- Remove UK record
          2- Press "Add new country" button which will perform a "saveAllEdits" action. Visually, UK record is removed. But I get the following JavaScript error stack trace:
          Code:
          *14:28:40.039:XRP7:WARN:Log:TypeError: Cannot read property '0' of undefined
          Stack from error.stack:
              ResultSet.get(<no args: exited>) on [ResultSet ID:isc_ResultSet_9 (dataSource: countryDS, created by: countryList)] @ [no file]:1876:30
              ListGrid.discardEdits(<no args: exited>) on[ListGrid ID:countryList] @ [no file]:2218:41
              ListGrid.removeDataComplete(<no args: exited>) on[ListGrid ID:countryList] @ [no file]:2351:486
              [c]Class.fireCallback(_1=>Obj, _2=>"dsResponse,data,dsRequest", _3=>Array[3], _4=>[RestDataSource ID:countryDS], _5=>undef) on [Class RestDataSource] @ [no file]:302:104
              Class.fireCallback(_1=>Obj, _2=>"dsResponse,data,dsRequest", _3=>Array[3], _4=>undef) on [RestDataSource ID:countryDS] @ [no file]:370:302
              DataSource.fireResponseCallbacks(_1=>Obj, _2=>Obj, _3=>Obj, _4=>Obj) on [RestDataSource ID:countryDS] @ [no file]:747:13
              DataSource._completeResponseProcessing(_1=>[XMLDoc <response>], _2=>Obj, _3=>Obj, _4=>Obj, _5=>Obj) on [RestDataSource ID:countryDS] @ [no file]:744:6
              DataSource._completeHandleXMLReply(_1=>Obj, _2=>Obj) on [RestDataSource ID:countryDS] @ [no file]:721:261
              [c]Class.fireCallback(<no args: recursion>)  on [Class RestDataSource] @ [no file]:302:104
              Class.fireCallback(<no args: recursion>)  on [RestDataSource ID:countryDS] @ [no file]:370:302
              DataSource._completeDSResponseFromXML(_1=>Array[1], _2=>Obj, _3=>undef, _4=>undef) on [RestDataSource ID:countryDS] @ [no file]:726:12
              [c]Class.fireCallback(<no args: recursion>)  on [Class RestDataSource] @ [no file]:302:104
              Class.fireCallback(<no args: recursion>)  on [RestDataSource ID:countryDS] @ [no file]:370:302
              DataSource.recordsFromXML(_1=>Array[1], _2=>Obj) on [RestDataSource ID:countryDS] @ [no file]:730:13
              DataSource.selectRecords(_1=>[XMLDoc <response>], _2=>Obj, _3=>Obj) on [RestDataSource ID:countryDS] @ [no file]:727:213
              DataSource.dsResponseFromXML(_1=>[XMLDoc <response>], _2=>Obj, _3=>Obj, _4=>Obj) on [RestDataSource ID:countryDS] @ [no file]:721:415
              DataSource._handleXMLReply(_1=>[XMLDoc <response>], _2=>"<!-- XML response to an remove request. ..."[349], _3=>Obj, _4=>Obj) on [RestDataSource ID:countryDS] @ [no file]:721:75
              [c]Class.fireCallback(<no args: recursion>)  on [Class XMLTools] @ [no file]:302:104
              $37c(_1=>Obj, _2=>"<!-- XML response to an remove request. ..."[349], _3=>Obj) on [Class XMLTools] @ [no file]:75:6
              [c]Class.fireCallback(<no args: recursion>)  on [Class RPCManager] @ [no file]:302:104
              Class.fireCallback(<no args: recursion>)  on [RPCManager ID:builtinApplication] @ [no file]:370:302
              [c]RPCManager.fireReplyCallback(_1=>Obj, _2=>Obj, _3=>Obj, _4=>"<!-- XML response to an remove request. ..."[349]) on [Class RPCManager] @ [no file]:1723:77
              [c]RPCManager.fireReplyCallbacks(_1=>Obj, _2=>Obj) on [Class RPCManager] @ [no file]:1730:120
              [c]RPCManager.performOperationReply(_1=>Obj, _2=>Obj) on [Class RPCManager] @ [no file]:1721:13
              RPCManager._performTransactionReply(_1=>17) on [Class RPCManager] @ [no file]:1701:6
              [c]RPCManager.performTransactionReply(_1=>17, _2=>"<!-- XML response to an remove request. ..."[349], _3=>undef) on [Class RPCManager] @ [no file]:1616:20
              eval(transactionNum=>17, results=>[object XMLHttpRequest], wd=>undef) @ [no file]:3:16
              [c]Class.fireCallback(<no args: recursion>)  on [Class Comm] @ [no file]:302:104
              [c]Comm.performXmlTransactionReply(_1=>17, _2=>[object XMLHttpRequest]) on [Class Comm] @ [no file]:1329:27
              eval(xmlHttpRequest=>[object XMLHttpRequest]) @ [no file]:3:10
              [c]Class.fireCallback(<no args: recursion>)  on [Class Class] @ [no file]:302:104
              Comm._fireXMLCallback(_1=>[object XMLHttpRequest], _2=>"isc.Comm.performXmlTransactionReply(17, ..."[55], _3=>undef) on [Class Comm] @ [no file]:1309:409
              XMLHttpRequest._13() @ [no file]:1316:1197

          Comment


            #6
            We've added a fix for this issue. It should be in the next nightly builds of SC 9.1p and newer.

            Comment


              #7
              Yes, it works now. Thanks.

              Comment

              Working...
              X