Announcement

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

    getAttributeAsDouble() is returning a string, when number has a large magnitude

    SmartClient Version: v12.1p_2021-10-22/PowerEdition Deployment (built 2021-10-22)

    I know that what I'm about to describe is very vague, but I'm hoping that it may trigger a memory of a past problem ( my forum search didn't reveal anything that I found useful), or trigger a suggestion.

    This is SmartGWT client side JAVA code.

    I have a TreeNode [] array, of which copyNode is one selected element of the array. The following is cut an pastes from the Chrome source debugger.

    This node appears to have this data, according to the debugger:

    Click image for larger version

Name:	ForumCopyNode_1.png
Views:	109
Size:	62.9 KB
ID:	266745


    Notice that the entry 'TNS' is stored as a string, it appears. I have checked the datasources and the TNS field is defined as a 'float'.

    In other entries of the TreeNode [] array when the value of TNS is many magnitudes smaller, eg -38.231 it appears to be stored as a 'float'

    Anyway my code does this simple arithmetic, and the value of the attr string is 'TNS' in this case:

    Double count = -0.764D;
    Double nV = 0.0D;

    nV = Double.valueOf(copyNode.getAttributeAsDouble(attr));

    count = count + Double.valueOf(nV);

    The result of executing the last line of code is that the variable count becomes a string: "-0.764-34726056.35200000" . A little later in the code I attempt to operate on the count variable, store it into a HashMap< String, Double> but that line throws a CastException when it executes with this value. No surprise.

    There are 60+ elements of the TreeNode [] array, and 58 of them execute with appropriate float values of 'TNS' entry and two of them have this exception when the TNS value is some large magnitude.

    What is happening under the hood in the Javascript that may be causing this? Any ideas?

    I have added the Double.valueOf( x ) in my code to see if this affected the Exception but it doesn't. The original code, that had this Exception too, was a simple:

    count += copyNode.getAttributeAsDouble(attr);

    I have broken out the code into smaller steps just to help debug.

    The unmodified code has been running successfully for many generations of 12.1 releases, but fails just in this edge case when the values of the 'TNS' entry get big. I have run the unmodified code on a July 15, 2021 version of 12.1 and it has the same exception. What I'm trying to say is that this Exception seems only dependent on the values of 'TNS'.

    Putting a sample test case together is almost impossible. If we have to we will arrange for a direct consultancy.






    #2
    No need for consultancy, we know exactly what this is, and it’s as designed and doc’d.

    Take a look at DataSourceField.stringInBrowser which covers both the rationale for the behavior (JavaScript’s Number type has precision limits) and how to change it, and what the trade offs are.

    Comment


      #3
      Thanks for the reply.

      I have yet to fully digest and attempt to use the instructions in DataSourceField.stringInBrowser , but my first question is this:

      Why does this usage not return a Double, rather than a string?

      nV = Double.valueOf(copyNode.getAttributeAsDouble(attr));

      It is definitely setting the value of nV to a string and not converting the string into a Double. That just doesn't make sense.

      Edit:

      Adding either (one) of these directives to the server.properties fixes my 'problem'.


      # Fixes Comparison Cast Exception on Double
      #datasource.disableStringInBrowser: true

      datasource.defaultStringInBrowser: false

      And I believe if I went through all of our datasources and added stringInBrowser="false" to each of the thousands of field definitions, that may work too, I still think that forcing the conversion of the string (as above ) to a Double in the Java should work, but it isn't.

      Last edited by tece321; 29 Oct 2021, 07:23.

      Comment


        #4
        Originally posted by tece321 View Post
        Thanks for the reply.

        I have yet to fully digest and attempt to use the instructions in DataSourceField.stringInBrowser , but my first question is this:

        Why does this usage not return a Double, rather than a string?

        nV = Double.valueOf(copyNode.getAttributeAsDouble(attr));

        It is definitely setting the value of nV to a string and not converting the string into a Double. That just doesn't make sense.
        What you're seeing is the result of GWT in "script" mode not strictly enforcing types, or doing any type conversion. In your case, although DataClass.getAttributeAsDouble() is typed as returning a Double, and Double.valueOf() is typed as accepting a double, the actual types in JavaScript will remain string if the attribute is actually a string. If you were to compile your code in "Classic Development" mode inside Eclipse, you'd hit an exception from the type mismatch, but not in "script" mode which is the current default.

        What you could do instead is use the code:
        Code:
        Double nV = Double.parseDouble(r.getAttribute(attr));
        This will handle a string attribute as you want, by converting it to a double, and will also pass through a double-valued attribute in GWT "script" mode, because of the same loose type handling that allowed your original example to run without throwing an exception.

        Comment


          #5
          Thanks.

          Yes that works fine. I think I may have to change all my float reads from Datasource fetches to assume it is returned as a string, and do the conversion on the client as you suggest.

          Comment

          Working...
          X