Announcement

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

    Bug? Floats converted as Strings in IE

    SmartGWT LGPL 6.0p, nightly build 2018-01-03, SmartClient Version: v11.0p_2018-01-03/LGPL Development Only (built 2018-01-03)

    We have a server backend that returns double precision floats from the database. We use these floats to order a list of items in a predicted order. We have been debugging an intermittent problem with IE family of browsers (tested with IE 10, 11 and Edge) where our whole component breaks down. By debugging, we noticed that the float values in records were for some reason Strings instead of numbers. The problem does not occur with Chrome or Firefox.

    For example, If we have a DataSourceFloatField in our data source and the server returns "325.71428571428584" for this field, with IE, the record ends up having an incorrect data type in the attribute (string instead of a number).

    We ran a debugger through this and noticed that DataSource.recordsFromXML call goes through Validators.js code which has this function in it we trip into:

    Code:
    ...
    isFloat: {
                type:"isFloat",
                description:"Value is a floating point number",
                valueType:"none",
                dataType:"none",            
                condition : function (item, validator, value) {
                        ...
                        // If stringInBrowser is not defined and loosing precision - leave string value.
                        if (isc.booleanValue(item.stringInBrowser, true) !== false && isc.isA.String(value) && lostPrecision) {
                            validator.resultingValue = value;
                            return true;
                        }
                        ...
    It seems that IE loses some precision on the float when there are so many digits returned from the database. Then the code leaves the value as a String which breaks down our app completely. Why is this? Is there a workaround that we could use to allow the loss of precision and return correctly typed Records instead of invalid records from the data source (in our case it would be preferred).

    By the way, wouldn't it be a more sensible runtime behavior to throw an Exception when a loss of precision is detected or at least log an error/warning we could trace the problem in to? Tracking this down from an obfuscated production code was a bit of a pain.


    #2
    Oddly, you dove into the code far enough to find a comment about the relevant property (dataSourceField.stringInBrowser), but don't seem to have read the docs for this property.. please do so now. It's an optional feature, which is very useful for preserving full precision for display of numbers that JavaScript can't represent accurately. Also, it's not browser-specific.

    Comment


      #3

      Ok, thanks. Granted - it was in the JavaDoc as long as we knew what to look for. As you might have guessed we are not using the server backend. So, something like

      Code:
          myFloatField.setAttribute("stringInBrowser", false);
      .. is the suggested workaround in the DataSource?

      When we actually found out the reason for the anomaly (type conversion error under the hood), we actually looked for properties that would have some effect on this via our IDE but the GWT wrapping classes have no setters or mentions of this kind of property. You basically just have to know it exists and read through the correct JavaDoc page to bump into it. Our first guess was, of course, some obscure floating point related bug in IE as it only seemed to occur randomly with IE browser. Because of the nature of this issue (acts differently in different browsers, very sporadic, very tricky to track down) it would be great to have a runtime warning or error to point to correct direction when this happens.
      Last edited by markok; 9 Jan 2018, 23:06.

      Comment


        #4
        Again, this is not a browser-specific behavior (see docs). Further, the alternative to leaving the value as a string is that precision will be dropped - same effect in all browsers, since JavaScript has the same precision in all browsers. If your application is relying on precision JavaScript can't handle, it's going to break no matter what the framework does (and the native parseFloat() doesn't log a warning when precision is dropped either).

        So at the moment you are claiming a browser-specific issue, which doesn't appear to be the case, and haven't explained what you hoped to happen, since again your choices are lost precision or keeping the value as a string. Right now we have no bug for which to suggest a "workaround". Further, we don't know what behavior you want; obviously you can add your own validator to force precision loss, but you seem to want something else.

        Comment


          #5
          We know your implementation is the same for all browsers. We got around the problem with the code presented above. Thanks for pointing out the property for to do this.

          We don't want anything, we merely suggested that when a developer types a data source field as a number and your framework under the hood suddenly converts it to a String, a warning or something might be a good idea.

          Browsers seem to have differences even though you say the precision should be the same. We know we are probably chasing rabbits here but with the code below,
          • Chrome prints out 325.71428571428584
          • IE11 (and in our experience most browsers of IE family) prints out 325.71428571428583 (?)
          No idea where this difference comes from. But as said, if we leave stringInBrowser unset, the effect of this is that with Chrome the values will be Numbers and in IE Strings (as the converted value does not match the original).

          Code:
                  viewport = new VLayout();
                  viewport.setWidth100();
                  viewport.setHeight100();
                  viewport.setOverflow(Overflow.HIDDEN);
          
                  final DataSource ds = new DataSource();
                  ds.setID("MyDS");
                  DataSourceFloatField floatField = new DataSourceFloatField("float");
                  floatField.setAttribute("stringInBrowser", false);
                  ds.setFields(floatField);
          
                  String src = "<MyDS><float>325.71428571428584</float></MyDS>";
                  Record[] records = ds.recordsFromXML(XMLTools.selectNodes(src, "/MyDS"));
          
                  Label l = new Label();
                  l.setContents(records[0].getAttribute("float"));
          
                  viewport.addMember(l);
                  viewport.draw();

          Comment


            #6
            We're not actually converting a float to a string. We're taking the string you provide and only converting to Number if the value can be accurately represented as a JavaScript Number. If we didn't do this, end users would enter a number in a field and see it changed inexplicably.

            That said, thanks for pointing out what appears to be some kind of IE bug in this area, and we do need to make it so that a setAttribute() call isn't require for LGPL users.

            Comment

            Working...
            X