makeWebRequest result issues

Former Member
Former Member
I'm using makeWebRequest and the data I get back should have an entry with the value 2861585482 for instance, but I get 2861585408.000000 instead. I think this has something to do with being over int max. Not sure if anyone else has experienced this issue or has any idea how to fix it?
  • It appears that if the parsed value is too large to be stored in Lang.Number, it is stored in Lang.Float. Here is the test case I'm using to demonstrate...

    using Toybox.Application as App;
    using Toybox.Lang as Lang;
    using Toybox.System as Sys;
    using Toybox.WatchUi as Ui;
    using Toybox.Graphics as Gfx;
    using Toybox.Communications as Comm;

    var _G_code;
    var _G_data;
    var _G_pending = false;

    var _G_files = [
    "number.json",
    "long.json",
    "float.json",
    "double.json"
    ];

    var _G_index = 0;

    class ZZZBehaviorDelegate extends Ui.BehaviorDelegate
    {
    function initialize() {
    BehaviorDelegate.initialize();
    }

    function onSelect() {
    if (!_G_pending) {
    _G_pending = true;
    _G_code = "";
    _G_data = _G_files[_G_index];

    var url = Lang.format("localhost:8000/$1$", [ _G_data ]);
    _G_index = (_G_index + 1) % _G_files.size();

    var params = {
    };

    var options = {
    };

    Comm.makeWebRequest(url, params, options, method(:onWebResponse));

    Ui.requestUpdate();
    }

    return true;
    }

    function onWebResponse(code, data) {
    _G_pending = false;

    _G_code = code;
    _G_data = data;

    if (_G_data != null) {

    for (var i = 0; i < _G_data.size(); ++i) {

    var type = "Unknown";
    if (_G_datainstanceof Lang.Number) {
    type = "Number";
    }
    else if (_G_datainstanceof Lang.Long) {
    type = "Long";
    }
    else if (_G_datainstanceof Lang.Float) {
    type = "Float";
    }
    else if (_G_datainstanceof Lang.Double) {
    type = "Double";
    }

    Sys.println(_G_data+ " is a " + type);
    }
    }

    Ui.requestUpdate();
    }
    }

    class ZZZView extends Ui.View
    {
    function initialize() {
    View.initialize();
    }

    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.clear();

    var cy = dc.getHeight() / 2;
    var cx = dc.getWidth() / 2;

    var color = Gfx.COLOR_GREEN;
    if (_G_pending) {
    color = Gfx.COLOR_RED;
    }

    dc.setColor(color, color);
    dc.fillCircle(cx, 10, 7);
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);

    if (_G_code != null) {


    var fy = dc.getFontHeight(Gfx.FONT_LARGE);

    dc.drawText(cx, cy - fy, Gfx.FONT_LARGE, _G_code.toString(), Gfx.TEXT_JUSTIFY_CENTER);

    if (_G_data != null) {
    dc.drawText(cx, cy, Gfx.FONT_XTINY, _G_data.toString(), Gfx.TEXT_JUSTIFY_CENTER);
    }
    }
    }
    }

    class ZZZApp extends App.AppBase
    {
    function initialize() {
    AppBase.initialize();
    }

    function getInitialView() {
    return [ new ZZZView(), new ZZZBehaviorDelegate() ];
    }
    }
    [/code]

    Here is the server I'm using to test this with...

    import BaseHTTPServer
    import json

    class MockRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def init(self):
    pass

    def do_GET(self):
    basename, extension = self.path.split('/')[1].split('.')

    message_body = {
    "number" : [ 2147483647, 2147483648 ],
    "long" : [ 9223372036854775807, 9223372036854775808 ],
    "float" : [ 1.175494e-38, 3.402823e+38 ],
    "double" : [ 2.2250738585072014E-308, 1.7976931348623157E+308 ],
    }.get(basename)

    if extension == "json":
    content_type = "application/json"
    message_body = json.dumps(message_body)
    else:
    content_type = "text/plain"
    message_body = str(message_body)

    self.send_response(200)
    self.send_header("Content-Type", content_type)
    self.send_header("Content-Length", len(message_body))
    self.end_headers()
    self.wfile.write(message_body)


    def _main():
    server_address = ('', 8000)

    httpd = BaseHTTPServer.HTTPServer(server_address, MockRequestHandler)
    httpd.serve_forever()


    if __name__=='__main__':
    _main()


    When I run this and press enter a few times in the simulator, I see this output...

    2147483647 is a Number
    2147483648.000000 is a Float
    9223372036854775800.000000 is a Float
    9223372036854775800.000000 is a Float
    0 is a Number
    340282306073709650000000000000000000000.000000 is a Float
    0 is a Number
    1.#INF00 is a Float


    This tells me that (at least when running under the simulator) the system treats values that cannot fit into Lang.Number as Lang.Float. No value that comes back will ever be treated as a Lang.Long or Lang.Double, which exposes apps to precision and type errors.

    It seems that there is an enhancement that could be made here. If is no no decimal point, then an attempt should be made to parse it as a Long. If that doesn't overflow, then an attempt should be made to convert that value to a Number. If the value fit, then the Number should be returned, otherwise the Long should be returned. If parsing the Long would overflow, fall through and parse the value as a Double. If that value can be converted to a Float without loss, a Float should be returned, otherwise the original Double should be returned.




    Travis
  • Former Member
    Former Member over 8 years ago
    Are there any plans to fix this so numbers returned from makeWebRequest are parsed into the correct type?
  • There was a problem where GCM Android was returning numbers as longs, but that's been fixed in 3.19.1

    See: https://forums.garmin.com/forum/developers/connect-iq/159584-

    Could this be involved?
  • Former Member
    Former Member over 8 years ago
    You are seeing this issue in the simulator, correct? If so, this was a known issue that has been fixed for the next release. If you see this when using GCM, that would be a different issue, and please let us know.
  • GCM iOS returns 2861585482 as Number -1433381814
  • Former Member
    Former Member over 8 years ago
    GCM iOS returns 2861585482 as Number -1433381814


    That would be a different known issue, where effectively a long is cast to an int. It should also be fixed in an upcoming release.