How to receive Lang.Array type on makeWebRequest

I am trying to improve the typing of my app, to be aware of potential runtime exceptions while compiling. The app is receiving JSON responses that consists of an array:

[]

The Communications.makeWebRequest() method expects

responseCallback as Lang.Method(responseCode as Lang.Number, data as Lang.Dictionary or Lang.String or Null)

Since Lang.Dictionary cannot be polymorphed into Lang.Array or the other way around, how can a Lang.Array be received with typing enabled?

One option would be to use Lang.Object, however, this is quite a general typing.

  • Type checking is pre-compile time only and has no impact when an app is running.

  • Unfortunately, when makeWebRequest() is used with HTTP_RESPONSE_CONTENT_TYPE_JSON, CIQ expects the response to be a JSON object (*), even though the following types are also valid JSON: array, number, string. (* I'm not sure if null is also an allowed response -- I haven't tested it.)

    Here's a forum thread where a Garmin employee addresses this:

    [https://forums.garmin.com/developer/connect-iq/f/discussion/310015/webrequest-how-to-ignore-wrong-response-content-type/1500937#1500937]

    So in the case of HTTP_RESPONSE_CONTENT_TYPE_JSON, the data passed to the callback will always be a Monkey C Dictionary (or possibly null). If the service returns something different, makeWebRequest will return a negative number as an error.

    I think your only options are:

    1) write a proxy service to wrap the response in an object

    2) Use HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN and parse the response yourself. Not only would this be possibly intensive in terms of code, memory and CPU (depending on the complexity of the response), but it also may not be possible depending on whether CIQ truly validates the response Content-Type or not (as per the docs). It also means that your app won't work on devices with CIQ < 3

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Communications.html

    HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN
    5

    API Level 3.0.0

    Content type specifier for response is expected to be plain text type. Content type string must be "text/plain"

    Also, in the same thread, someone posted that it works on Android and not iOS (keep in mind the thread is over one year old).

  • Sorry for the late reply (received no notifications at all). Thanks for your responses!

    Receiving Arrays works fine in the final app. It is even possible to test if the data is an instanceof Lang.Array. The issue is, that according to the typing of the callback functions, it is not possible to receive a Lang.Array type. The same goes for responses that return a Media.ContentRef type (e.g. when makeWebRequest is called with :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_AUDIO). The callback typing does not include those types.

    This means that the typing is incorrect, and will cause errors and crashes, even though the strict typechecker will say everything is okay.