Page 3 of 3

Manipulate REST output before JSON parsing

Posted: Sun Jan 13, 2013 12:09 am
by Emmz

If the server response is nothing. but code is 200. Success and complete events are fired.
I Alway use complete event and read jqXHR on that event.

I have over 50 types of rest service that operate in different ways. Use events that run other events etc. There are no problems in Tiggzi or Jquery for rest calls or processing.


Manipulate REST output before JSON parsing

Posted: Sun Jan 13, 2013 12:11 am
by Renjith V

I agree to all the arguments. But the events are just not fired. Anyone tried using a REST service that returns a 200 code, but not a JSON formatted output?


Manipulate REST output before JSON parsing

Posted: Sun Jan 13, 2013 12:12 am
by Renjith V

As I told before, the service is invoked, it returns the string "None" and the json parse throws and exception. My whole aim is to update the string to a valid string before parsing happens. Again, none of the events are called and I am unable to get a callback before the parsing happens.


Manipulate REST output before JSON parsing

Posted: Sun Jan 13, 2013 12:13 am
by Emmz

I have spinner hidden from the start. Yes its clean. Then I decide under what conditions I want the spinner to show and to what degree. ie. Not allow user input or only show activity while allowing user input. etc.
I have all my rest services on the menu screen. And with 15 + screens. Make rest calls and store if off-line and run them if on-line.


Manipulate REST output before JSON parsing

Posted: Sun Jan 13, 2013 12:33 am
by maxkatz

Even if the response is not JSON formatted, one of the callback handlers should still fire.

Did you try using Chrome Dev. Tools Network tab to view the response?


Manipulate REST output before JSON parsing

Posted: Mon Jan 14, 2013 6:22 pm
by Emmz

Yes Completed always fires. Unless server rtns error 404 or similar


Manipulate REST output before JSON parsing

Posted: Sat Apr 27, 2013 5:45 pm
by Michael Johnson

I am experiencing this same problem, and I have verified that the error "SyntaxError: JSON.parse: unexpected keyword" occurs before any callback handler is invoked.

My service complete handler includes the code:
precode
var responseTxt =(jqXHR.responseText);
console.log(responseTxt);
/code/pre

I am calling a search query on my REST service. When I call it with a valid search I get JSON back, but when no results are available it returns invalid JSON (returns the string "No Results").

My console log looks like the following:
precode
[13:17:40.407] GET http://appery.io/app/rest/tunnel?criteria=foo [HTTP/1.1 200 OK 655ms]
[13:17:41.031] [{ a valid JSON response containing objects that match the search string 'foo', printed by my complete handler}]
[13:17:55.000] GET http://appery.io/app/rest/tunnel?criteria=x [HTTP/1.1 200 OK 402ms]
[13:17:55.350] SyntaxError: JSON.parse: unexpected keyword @ http://appery.io/app/resources/preview/lib/jquery/jquery-1.8.2.js:514
/code/pre

I have no valid objects containing 'x' on my REST service, so the second response was "No Results" and the error occurred before my handler was invoked. The call stack confirms that this is the result of jQuery attempting to parse the JSON before it even returns from the $.ajax() call.

I tried using service_name.execute({}) wrapped in a try...catch instead of directly invoking the service, but for some unknown reason, the catch is never reached. I assume the actual $.ajax call is being handled via an event callback that is escaping my try...catch.

The way I normally handle this in my own web apps, when the REST service is unreliable and sometimes returns content that is not JSON-formatted, is to set the $.ajax dataType to 'text' and parse the results myself. I think that would be a good option for Appery -- allow the request type to be text -- although it would be tricky because JavaScript to parse the text would no longer be optional.

I still have no workaround for this. I am trying to figure out if I can configure or monkeypatch jQuery to behave.


Manipulate REST output before JSON parsing

Posted: Sat Apr 27, 2013 7:19 pm
by Michael Johnson

Actually I am not even understanding where this error comes from because: codeJSON.parse('"No Results"')/code returns the JavaScript string "No Results" without any error. Obviously not a valid JSON object, but doesn't cause an exception. Going to have to debug more carefully...

I hacked a workaround with $.ajaxSetup() as follows, although replacing the bad JSON with null is not really the behavior I want:
precode
$.ajaxSetup({
dataFilter: function(data, type) {
var output = data;
if (type === "json" && typeof data === "string") {
try {
data = jQuery.trim(data);
var result = JSON.parse(data);
if (typeof result === 'string') {
output = null;
}
} catch(err) {
output = null;
}
}
return output;
}
});
/code/pre


Manipulate REST output before JSON parsing

Posted: Mon Apr 29, 2013 5:58 am
by Kateryna Grynko

Hi Michael,

JSON.parse('"No Results"') works because you send "No Results" to parser - it's a correct JSON, but in response you probably get No Results and parser gets JSON.parse('No Results')
Try to rewrite $.parseJSON.
code$.parseJSON = function ( data ) {
try {
if ( !data || typeof data !== "string") {
return null;
}

Code: Select all

                 // Make sure leading/trailing whitespace is removed (IE can't handle it) 
                 data = jQuery.trim( data ); 

                 // Attempt to parse using the native JSON parser first 
                 if ( window.JSON && window.JSON.parse ) { 
                         return window.JSON.parse( data ); 
                 } 

                 // Make sure the incoming data is actual JSON 
                 // Logic borrowed from http://json.org/json2.js 
                 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 
                         .replace( rvalidtokens, "]" ) 
                         .replace( rvalidbraces, "")) ) { 

                         return ( new Function( "return " + data ) )(); 

                 } 
                 jQuery.error( "Invalid JSON: " + data ); 
         }  
         catch( e ) { 
            return {"incorrectJSON": data}; 
         } 

}/code
If JSON is incorrect you'll get an object with attribute incorrectJSON with a string.