Announcement

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

    _1.replace is not a function: at Object.makeXMLSafe - Execption thrown on Form.submit ( DSCallback, DSRequest);

    I'm doing something wrong, but can't figure it out in various experiments I have tried. Hoping you can help.

    Here is a synopsis of the issue. I have a Dynamic Form, bugForm. It contains a few TextBoxes, ComboBoxes and MultiComboBoxes. There is a 'Submit' button and a File Another checkBox. If the File Another check box is selected, the form clears itself after the response to the bugForm.submit() call, and the user can make a second set of choices, and can click the submit button a second time.

    Everything works fine on the first submit, data is sent, recorded in the SQL DB, and success response returned. If the FIle Another checkBox is false in the submit() DSCallback the form bugForm is destroyed(), else the bugForm.reset() is called, and the values cleared.

    But if the form is submitted a SECOND time, because the File Another checkbox was selected, and the user has input new form data, the bugForm.submit() call fires this exception:

    _1.replace is not a function: at Object.makeXMLSafe

    Here's a quick outline of the code

    Code:
          final DynamicForm bugForm = new DynamicForm();
            bugForm.setWidth100();
            bugForm.setAutoHeight();
            bugForm.setLayoutAlign(Alignment.CENTER);
            bugForm.setDataSource(DataSource.get("JIRA"));
            bugForm.setUseAllDataSourceFields(true);
            bugForm.setCellPadding(10);
            bugForm.setColWidths("33%", "66%");
            bugForm.setAlign(Alignment.CENTER);
            bugForm.setSaveOperationType(DSOperationType.ADD);
    
    // some ComboBoxItems,  TextItems,  and AutoFitTextAreaItems are added as fields to the form.
    //  The checkBox and IButton are added to a HLayout called buttons.   They are not members of the Dyn. Form.
    
    // A DSCallback and DSRequest are defined
    
    final DSCallback fileCallback = new DSCallback() {
    
                @Override
                public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                    if (dsResponse.getStatus() < 0) {
                        buttons.setDisabled(false);
                        SC.say(dsResponse.getDataAsString());
                    } else {
                        SC.say(dsResponse.getDataAsString());
                        if (Boolean.TRUE.equals(anotherBug.getValueAsBoolean())) {
                            bugForm.reset();
                            extraChoicesForm.reset();
                            buttons.setDisabled(false);
                            anotherBug.setValue(false); // Or user will repeated file JIRAs
                        } else {
                            destroy();
                        }
                    }
                }
            };
    
    final DSRequest reqProp = new DSRequest();
            reqProp.setWillHandleError(true);
            reqProp.setOperationType(DSOperationType.ADD);
            reqProp.setDataSource("JIRA");
    
    // The submit button gets this handler:
    
    
    submit.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
    
                @Override
                public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) {
                    if (bugForm.validate()) {
                        buttons.setDisabled(true);
                        loading.show();
    
                        if (jiraComponents.getValue() != null && !jiraComponents.getValueAsString().isEmpty()) {
                            bugForm.setValue("Component", jiraComponents.getValue().toString());
                        }
                        else if (defaultComponent != null) {
                            bugForm.setValue("Component", defaultComponent.toString());
                        }
                        if ( jiraVersion.getValueAsString() != null && ! jiraVersion.getValueAsString().isEmpty() ) {
                            bugForm.setValue("Version", jiraVersion.getValueAsString());
                        }
    
                        bugForm.submit(fileCallback, reqProp);
                    }
                }
            });
    When this bugForm.submit is called the SECOND time, I get the internal exception described above.

    Can you tell what I have forgotten to initialize the second time the submit.addClickHandler is called?

    thanks

    #2
    Hmm, hard to tell from this. The first thing that comes to mind is possibly calling methods on a destroy()d form.

    However, that particular crash also suggests that a field that was expected to have a String value instead had some non-null, non-String value, like a JS Object, which could occur if the server returned values from the update that included some kind of Java object that was not a String and ended up serialized to the client as a JS Object. You would be able to see this in the RPC tab in the response as something like this:

    Code:
    [I]stringFieldName [/I]: { ... various properties ... }
    You may also be able to inspect form.values (from the Developer Console) and see that something that is supposed to be a String isn't.

    If you can get a stack trace for the JS error (see Debugging topic in reference) that would help too.

    Comment


      #3
      This is what the Developer Console shows as the DSRequest generated on the SECOND submit:

      Code:
      {
          dataSource:"JIRA",
          operationType:"add",
          operationId:{
              ID:"JIRA_add",
              dataSource:"JIRA",
              type:"add",
              filterType:"paged",
              loadDataOnDemand:true,
              source:"auto"
          },
          componentId:"isc_DynamicForm_7",
          data:{"0":"S","1":"u","2":"c","3":"c","4":"e","5":"s","6":"s","7":"f","8":"u","9":"l","10":"l","11":"y","12":" ","13":"c","14":"r","15":"e","16":"a","17":"t","18":"e","19":"d","20":" ","21":"J","22":"I","23":"R","24":"A","25":":","26":" ","27":"<","28":"a","29":" ","30":"t","31":"a","32":"r","33":"g","34":"e","35":"t","36":"=","37":"\"","38":"_","39":"b","40":"l","41":"a","42":"n","43":"k","44":"\"","45":" ","46":"h","47":"r","48":"e","49":"f","50":"=","51":"\"","52":"h","53":"t","54":"t","55":"p","56":"s","57":":","58":"\\","59":"\\","60":"j","61":"i","62":"r","63":"a","64":".","65":"b","66":"r","67":"o","68":"a","69":"d","70":"c","71":"o","72":"m","73":".","74":"n","75":"e","76":"t","77":"\\","78":"b","79":"r","80":"o","81":"w","82":"s","83":"e","84":"\\","85":"F","86":"L","87":"B","88":"E","89":"E","90":"R","91":"-","92":"1","93":"3","94":"1","95":"8","96":"\"","97":">","98":"F","99":"L","100":"x","101":"x","102":"x","103":"x","104":"-","105":"1","106":"3","107":"1","108":"8","109":"<","110":"/","111":"a","112":">","Project":"FLBEER","Component":"[FL-db, FL-general, FL-ui]","Version":"Chip STA 2.0.0","Class":"String","multiplierKB":1024,"multiplierMB":1048576,"multiplierGB":1073741824,"IssueType":"New Feature","Summary":"Tony Test 4141","Description":"4141414141","Priority":"4","Assignee":"to920136"},
          textMatchStyle:"exact",
          callback:{
              target:[DynamicForm ID:isc_DynamicForm_7],
              methodName:"saveEditorReply"
          },
          willHandleError:true,
          showPrompt:true,
          prompt:"Saving form...",
          oldValues:{
          },
          requestId:"JIRA$62751",
          internalClientContext:{
          },
          fallbackToEval:false,
          afterFlowCallback:"isc_DynamicForm_7.$49z(dsRequest, dsResponse, data)",
          editor:[DynamicForm ID:isc_DynamicForm_7],
          lastClientEventThreadCode:"MUP5",
          bypassCache:true,
          dataProtocol:"getParams"
      }
      The response to the FIRST bugForm.submit() returned this:

      Code:
      affectedRows:0,
          data:"Successfully created JIRA: <a target=\"_blank\" href=\"https:\\\\jira.xxxxxx.net\\browse\\FLxxxx-1318\">FLxxxx-1318</a>",
          invalidateCache:false,
          isDSResponse:true,
          operationType:"add",
          queueStatus:0,
          status:0,
      So we can see that the form now contains some form (?) of the FIRST response.

      I will try and set bugForm.setData( new Record() ), and see if that clears the exception.

      Thanks for the advice.

      Comment


        #4
        Next trial.

        I change the reset/clear logic in the submit() DSCallback to this:

        Code:
        final DSCallback fileCallback = new DSCallback() {
        
                    @Override
                    public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                        if (dsResponse.getStatus() < 0) {
                            buttons.setDisabled(false);
                            SC.say(dsResponse.getDataAsString());
                        } else {
                            SC.say(dsResponse.getDataAsString());
                            if (Boolean.TRUE.equals(anotherBug.getValueAsBoolean())) {
        // bugForm.resetValues();
        // bugForm.clearValues();
                                bugForm.editNewRecord();
                                extraChoicesForm.reset();
                                buttons.setDisabled(false);
                                anotherBug.setValue(false); // Or user will repeated file JIRAs
                            } else {
                                destroy();
                            }
                        }
                    }
                };

        Where I set new Record on the bugForm. This behaves better, in some respects, but still throws an exception:

        Code:
        === 2021-12-17 08:45:39,261 [1789] DEBUG PoolableDataSourceFactory - Tried to create DataSource of type 'transaction' but null was returned
        === 2021-12-17 08:45:39,262 [1789] DEBUG PoolableDataSourceFactory - Created DataSource 8560 of type 'Object' and assigned it to thread qtp2011126015-1789
        === 2021-12-17 08:45:39,262 [1789] DEBUG PoolableDataSourceFactory - Created DataSource 8561 of type 'List' and assigned it to thread qtp2011126015-1789
        === 2021-12-17 08:45:39,262 [1789] DEBUG PoolableDataSourceFactory - Tried to create DataSource of type 'elem' but null was returned
        === 2021-12-17 08:45:39,262 [1789] DEBUG RPCManager - Processing 1 requests.
        === 2021-12-17 08:45:39,263 [1789] ERROR IDACall - com.isomorphic.servlet.IDACall top-level exception
        java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.lang.String
            at com.isomorphic.datasource.DSRequest.getOperation(DSRequest.java:959)
            at com.isomorphic.datasource.DSRequest.setRequestData(DSRequest.java:554)
            at com.isomorphic.datasource.DSRequest.<init>(DSRequest.java:771)
            at com.isomorphic.rpc.RPCManager.parseRequest(RPCManager.java:2694)
            at com.isomorphic.rpc.RPCManager.<init>(RPCManager.java:435)
            at com.isomorphic.rpc.RPCManager.<init>(RPCManager.java:415)
            at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:147)
            at com.isomorphic.servlet.IDACall._processRequest(IDACall.java:119)
            at com.isomorphic.servlet.IDACall.doPost(IDACall.java:79)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
            at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:178)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
            at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
            at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
            at beer.server.NoCache.doFilter(NoCache.java:31)
            at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
            at com.isomorphic.servlet.CompressionFilter._doFilter(CompressionFilter.java:263)
            at com.isomorphic.servlet.BaseFilter.doFilter(BaseFilter.java:91)
            at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
            at beer.server.DevelopmentAuthenticationFilter.doFilter(DevelopmentAuthenticationFilter.java:51)
            at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
            at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224)
            at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
            at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
            at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
            at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553)
            at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
            at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
            at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
            at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
            at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
            at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
            at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
            at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95)
            at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
            at org.eclipse.jetty.server.Server.handle(Server.java:499)
            at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
            at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
            at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
            at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
            at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
            at java.lang.Thread.run(Thread.java:748)
        The Developer Console displays a strange (?) construction of the RPCRequest and DSRequest:

        Code:
        // RPCRequest:
        {
            "actionURL":"http://10.75.224.44:8815/beer/sc/IDACall",
            "showPrompt":true,
            "prompt":"Saving form...",
            "transport":"xmlHttpRequest",
            "promptStyle":"cursor",
            "bypassCache":true,
            "data":{
                "values":{
                    "IssueType":"Bug",
                    "Summary":"Tony Test 616161",
                    "Description":"616161",
                    "Priority":"4",
                    "Assignee":"to920136",
                    "Component":"[ECPM, FL-BEER-FW]",
                    "Version":"Chip STA 2.0.0"
                },
                "operationConfig":{
                    "dataSource":"JIRA",
                    "repo":null,
                    "operationType":"add",
                    "textMatchStyle":"exact"
                },
                "componentId":"isc_DynamicForm_7",
                "appID":"builtinApplication",
          "operation":{
                    "ID":"JIRA_add",
                    "dataSource":"JIRA",
                    "type":"add",
                    "filterType":"paged",
                    "loadDataOnDemand":true,
                    "source":"auto"
                },
                "oldValues":{
                }
            }
        }
        
        
        // DSRequest
        {
            dataSource:"JIRA",
            operationType:"add",
          operationId:{
                ID:"JIRA_add",
                dataSource:"JIRA",
                type:"add",
                filterType:"paged",
                loadDataOnDemand:true,
                source:"auto"
            },
            componentId:"isc_DynamicForm_7",
            data:{
                IssueType:"Bug",
                Summary:"Tony Test 616161",
                Description:"616161",
                Priority:"4",
                Assignee:"to920136",
                Component:"[ECPM, FL-BEER-FW]",
                Version:"Chip STA 2.0.0"
            },
            textMatchStyle:"exact",
            callback:{
                target:[DynamicForm ID:isc_DynamicForm_7],
                methodName:"saveEditorReply"
            },
            willHandleError:true,
            showPrompt:true,
            prompt:"Saving form...",
            oldValues:{
            },
            requestId:"JIRA$62751",
            internalClientContext:{
            },
            fallbackToEval:false,
            afterFlowCallback:"isc_DynamicForm_7.$49z(dsRequest, dsResponse, data)",
            editor:[DynamicForm ID:isc_DynamicForm_7],
            lastClientEventThreadCode:"MUP5",
            bypassCache:true,
            dataProtocol:"getParams"
        }
        There is a Map as the content of the OperationId field, which probably explains the exception:

        java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.lang.String

        But how did the Operation ID get transformed into a HashMap, and what have I to do to correct this?

        Here is what the DSRequest looked like on the successful FIRST press of the submit button ( note that the data submitted by the Form is different, as expected, between the FIRST and SECOND)


        Code:
        {
            dataSource:"JIRA",
            operationType:"add",
            componentId:"isc_DynamicForm_7",
            data:{
                Project:"FLBEER",
                IssueType:"New Feature",
                Summary:"Tony Test 6060",
                Description:"60606606060",
                Priority:"4",
                Assignee:"to920136",
                Component:"[Chip-STA, Dashboard]",
                Version:"BEER 2.0.0"
            },
            textMatchStyle:"exact",
            callback:{
                target:[DynamicForm ID:isc_DynamicForm_7],
                methodName:"saveEditorReply"
            },
            willHandleError:true,
            showPrompt:true,
            prompt:"Saving form...",
            oldValues:{
            },
            requestId:"JIRA$62749",
            internalClientContext:{
            },
            fallbackToEval:false,
            afterFlowCallback:"isc_DynamicForm_7.$49z(dsRequest, dsResponse, data)",
            editor:[DynamicForm ID:isc_DynamicForm_7],
            lastClientEventThreadCode:"MUP5",
            bypassCache:true,
            dataProtocol:"getParams"
        }
        Suggestions?

        Comment


          #5
          Your response is not valid - the expected response for a DataSource "add" operation is the record-as-saved. It's only valid to set "data" to a simple String when you are reporting a total failure of the "add".

          The system took your String and treated it like an Object, applying it as the form's new values - that's why you see each numbered letter in "data" on the second submit.

          If you just correct your response, that will likely solve all these downstream consequences.

          Comment


            #6
            Thanks.

            But in my response success case I want to respond not with the 'record-as-saved' but with a String with embedded information - in this case the successful creation of a JIRA in the form of a HTML URL.

            Should this be added as DSResponse.setProperty( "JIRA", " < html coded response > : ) on the server, and then retrieved on the client?

            Or

            should I add a field, say "JIRA" to the data map on the server and extract that on the client?

            How exactly do you suggest I get this out of band success message back to the client?

            Comment


              #7
              Normally, any such success message would be part of the UI code, so that it's easy to localize along with other application strings. But if for some reason it has to be server-generated, then yes, declaring a DSField for it would be the simplest way to get it to the client.

              Comment


                #8
                Thanks.

                The suggestion of adding a DSField of type text is the simplest and best answer. We will read that field in the client Response DSCallback to retrieve the status.

                Comment

                Working...
                X