makeJsonRequest/makeWebRequest examples

Code in simulator returns error INVALID_HTTP_BODY_IN_NETWORK_RESPONSE = -400. Neither makeJsonRequest nor makeWebRequest works properly.
Comm.makeJsonRequest(
"myfileaddress.example/file.txt",
{
},
{
"Content-Type" => Comm.REQUEST_CONTENT_TYPE_URL_ENCODED
},
method(:onReceive)
);


File on server is JSON text file. Server returns:
Content-Type: text/plain; charset=windows-1251

Tried parameter REQUEST_CONTENT_TYPE_JSON - the same result.
curl returns content on this address, so server is alive and url is correct.
Please could you provide examples with all the parameters description? Why it is changed? Sorry, I can't understand how to use everything specified in documentation, not obvious. It worked in the past when app was developed (1.2.9 SDK as I remember).

I am interested how to use these constants:
HTTP_RESPONSE_CONTENT_TYPE_JSON = 0
The expected response from making a web request
Since:
1.3.0
HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED = 1
Since:
1.3.0
REQUEST_CONTENT_TYPE_URL_ENCODED = 0
These values are used in conjunction with the “Content-Type” header key.

Specifies a content type of application/x-www-form-urlencoded
Since:
1.2.0
REQUEST_CONTENT_TYPE_JSON = 1
Specifies a content type of application/json
Since:
1.2.0
  • When you send a request with a Content-Type header, that simply tells the server the format of the request content. It should not have any impact on the format of the data that the server sends back. Typically an Accept header (documentation here) is used by the client to tell the server software what type of data the client will be able to process.

    Most likely the server is sending the content with type text/plain because the file extension requested is .txt (if you are using apache, you should have a peek at the documentation for mod_mime which is responsible for mapping the file extension to a content type). If you control the resource on the server, you should be able to resolve the problem by changing the file extension to .json.

    Travis
  • If I change url to .json it works.
    It looks odd. Why cannot it work as previous SDK worked? Now I need to have 2 file versions on server (to support old version of the app).

    SDK does not follow Monkey principle. I request file by makeJsonRequest, and it will be json there, no matter what it written in URL or content-type. Why text/plain cannot include json? If you are trying to avoid binary streams, then there is another method to analyze this. Fake header will stop system working, neat.
  • Why cannot it work as previous SDK worked?

    The server reports that the data is text/plain (i.e., it isn't formatted json). Garmin is now using the Content-Type header in an attempt to avoid trying to parse data that will most likely fail (assuming the content matches the content-type provided in the response). This may have been an optimization, or it may have been an attempt to avoid crashing the phone app or the device.

    Now I need to have 2 file versions on server (to support old version of the app).

    There are other ways to solve the problem. You can use file system links (so there is only one file, and the other is a link), or tweak your apache settings so that it serves .txt files as application/json. I'm sure there are more options.

    I request file by makeJsonRequest, and it will be json there, no matter what it written in URL or content-type.

    No. This is not necessarily true. If you call makeJsonRequest("http://www.google.com", ...) the result will not be json data. You can try and get the server to provide the data as application/json by adding an Accept: application/json header to the request, but I'm fairly certain that the server will just report a 4XX error code.

    Why text/plain cannot include json?

    Because not all text/plain content is application/json content. i.e., there are many plain text documents that are not json formatted.
  • Ok, let it be Garmin's decision to do so. We will just follow provided scheme. There should be mentioned that SDK recognizes headers now, and it _does_ matter for proper functionality.
    Still have a hope to see some examples with all the mentioned constants.
  • Those constants simply control how the request body is encoded. It is either urlencoded or encoded as json. How they are encoded should only matter if the service you are talking to requires the data to be formatted in a certain way.

    Note, you should write all new code using makeWebRequest. The function makeJsonRequest is deprecated.

    var params = {
    "a" => 1,
    "b" => 2
    };

    var headers = {

    // body will be encoded as 'a=1&b=2'
    "Content-Type" => Comm.REQUEST_CONTENT_TYPE_URL_ENCODED

    // body will be encoded as '{ "a" : 1, "b" : 2 }'
    // "Content-Type" => Comm.REQUEST_CONTENT_TYPE_JSON,

    // accept responses that are reported as json-compatible
    // "Accept" => "application/json"
    };

    var options = {
    :method => Comm.HTTP_REQUEST_METHOD_POST,
    :headers => headers
    };


    Comm.makeWebRequest(
    "localhost:8080/test", params, options, method(:onReceive)
    );
  • Former Member
    Former Member over 8 years ago
    Have you tried explicitly setting the response content type via the options? See the :responseType of the options hash in the API docs.

    Comm.makeJsonRequest(
    "myfileaddress.example/file.txt",
    {
    },
    {
    :headers -> {
    "Content-Type" -> Comm.REQUEST_CONTENT_TYPE_URL_ENCODED
    },
    :responseType -> Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON
    },
    method(:onReceive)
    );
  • Thanks, Ken, your code for CIQ must have => operators, not the -> and it gets compiled.

    Comm.makeJsonRequest(
    "myfileaddress.example/file.txt",
    {
    },
    {
    :headers => {
    "Content-Type" => Comm.REQUEST_CONTENT_TYPE_URL_ENCODED
    },
    :responseType => Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON
    },
    method(:onReceive)
    );


    I know about deprecated function and still will use it until epix is alive.

    I've combined your and Travis code to get following (I don't need to POST anything):
    var params = {};

    var options = {
    :method => Comm.HTTP_REQUEST_METHOD_GET,
    :responseType => Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON
    };

    Comm.makeJsonRequest(
    "myfileaddress.example/file.txt", params, options, method(:onReceive)
    );

    It works for me, as I know text file stores json, server headers are text/plain and it is ok and will not be changed. I feel good, thank you all! It would be great to add full example with all parameters to the docs.
  • Former Member
    Former Member over 8 years ago
    makeWebRequest problem for XML, okay JSON

    I have used a lot time on trial-and-error for the makeWebRequest function. Using a very simple service it works for JSON, but not for XML.

    var url = "www.broadbandmap.gov/.../nation";
    // WORKS
    Comm.makeWebRequest(url, {"format" => "json"}, {}, method(:onReceive));
    // FAILS for XML with responseCode "Failed to load Error: -400"
    Comm.makeWebRequest(url, {}, {}, method(:onReceive));


    For the XML scenario I have tried all sorts of different options, but always fails. Anyone who can make an working example?
  • I've answered your question in your original post.