Search code examples
javascriptgwtgetjsonjsni

GWT - how handle returned Json as primitive type


I need to get value from json. It works perfectly on returned objects, but sometimes I get just json value - like boolean. And I'm unable to get it from returned json in GWT.

I have JSNI function getJson() for retrieving json same as GWT tutorial StockWatcher. I guess this is relevant part of that function, where returned string is converted to JavaScriptObject ?

    // [2] Define the callback function on the window object.
        window[callback] = function(jsonObj) {
            // [3]
            [email protected]::handleJsonResponse(Lcom/google/gwt/core/client/JavaScriptObject;)(jsonObj);
            window[callback + "done"] = true;
        }
    // [4] JSON download has a timeout.
        setTimeout(
                function() {
                    if (!window[callback + "done"]) {
                        [email protected]::handleJsonResponse(Lcom/google/gwt/core/client/JavaScriptObject;)(null);
                    }

                    // [5] Cleanup. Remove script and callback elements.
                    document.body.removeChild(script);
                    delete window[callback];
                    delete window[callback + "done"];
                }, timeout);

It calls handler function, which is also based on tutorial.

    public void handleJsonResponse(JavaScriptObject jso){
    // if an ERROR
    if (jso == null) {
        this.module.onError();
        return;
    }
    // OK
    this.module.onFinished(jso);
}

Problem is. When I recieve boolean value, it's not parsed as JavaScriptObject and I end up in onError() caused by timeout.

Returned json string looks like: callback5(true); and it's returned long time before timeout. So I think, getJson() just can't parse it ?

How can I parse it into JavaScriptObject to work with rest of my program ? I guess i need some IF statement in section [3] of getJson() to decide what value type was returned a what handler function to call. Maybe create object manualy from returned value here and then pased it to existing handler. But I'm not sure how to do it corectly. I tried to create overlayType for boolean, but it's no help, since returned string is not parsed as jso anyway.

Thanks for any help.


Solution

  • Bare primitive types are not valid JSON. JSON strings (as defined here) must be either JavaScript objects or arrays. If you can't change the service from which the primitive types are coming you can pad the strings containing primitive types so that they can be parsed (into a single element array):

    function padPrimitiveType(json) {
      if (json != null && json[0] != '[' && json[0] != '{') {
        return "[" + json + "]";
      } else {
        return json;
      }
    }