Thursday, May 31, 2012

jQuery won"t parse my JSON from AJAX query


I'm having difficulty parsing some JSON data returned from my server using jQuery.ajax()



To perform the AJAX I'm using:




$.ajax({
url: myUrl,
cache: false,
dataType: "json",
success: function(data){
...
},
error: function(e, xhr){
...
}
});



And if I return an array of items then it works fine:




[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]



The success function is called and receives the correct object.



However, when I'm trying to return a single object:




{ title: "One", key: "1" }



The error function is called and xhr contains 'parsererror'. I've tried wrapping the JSON in parenthesis on the server before sending it down the wire, but it makes no difference. Yet if I paste the content into a string in Javascript and then use the eval() function, it evaluates it perfectly.



Any ideas what I'm doing wrong?



Anthony


Source: Tips4all

19 comments:

  1. Is your server sending data as Content-Type "*/json"? If not, modify the response headers accordingly. Sending "application/json" would be fine, for example.

    ReplyDelete
  2. According to the json.org specification, your return is invalid. The names are always quoted, so you should be returning

    { "title": "One", "key": "1" }


    and

    [ { "title": "One", "key": "1" }, { "title": "Two", "key": "2" } ]


    This may not be the problem with your setup, since you say one of them works now, but it should be fixed for correctness in case you need to switch to another JSON parser in the future.

    ReplyDelete
  3. JSON strings are wrapped in double quotes; single quotes are not a valid substitute.

    {"who": "Hello World"}


    is valid but this is not...

    {'who': 'Hello World'}


    Whilst not the OP's issue, thought it worth noting for others who land here.

    ReplyDelete
  4. Try adding this:

    $.ajax({
    type: "GET",
    url: myURL,
    beforeSend: function(x) {
    if(x && x.overrideMimeType) {
    x.overrideMimeType("application/j-son;charset=UTF-8");
    }
    },
    dataType: "json",
    success: function(data){
    // do stuff...
    }
    });

    ReplyDelete
  5. { title: "One", key: "1" }


    Is not what you think. As an expression, it's an Object literal, but as a statement, it's:

    { // new block
    title: // define a label called 'title' for goto statements
    "One", // statement: the start of an expression which will be ignored
    key: // ...er, what? you can't have a goto label in the middle of an expression
    // ERROR


    Unfortunately eval() does not give you a way to specify whether you are giving it a statement or an expression, and it tends to guess wrong.

    The usual solution is indeed to wrap anything in parentheses before sending it to the eval() function. You say you've tried that on the server... clearly somehow that isn't getting through. It should be waterproof to say on the client end, whatever is receiving the XMLHttpRequest response:

    eval('('+responseText+')');


    instead of:

    eval(responseText);


    as long as the response is really an expression not a statement. (eg. it doesn't have multiple, semicolon-or-newline-separated clauses.)

    ReplyDelete
  6. see this issue in JQuery 1.4.1, which was fixed in 1.4.2

    6031 parseJSON doesn't parse JSON with a leading newline in IE6 and IE7

    http://dev.jquery.com/ticket/6031

    Hope that helps... (it worked for me nicely).

    ReplyDelete
  7. I had this issue and for a bit I used

    eval('('+data+')')


    to get the data returned in an object. but then later had other issues getting a 'missing ) in parenthetical' error and found out that jQuery has a function specifically for evaluating a string for a json structure:

    $.parseJSON(data)


    should do the trick. This is in addition to having your json string in the proper format of course..

    ReplyDelete
  8. If you are consuming ASP.NET Web Services using jQuery, make sure you have the following included in your web.config:

    <webServices>
    <protocols>
    <add name="HttpGet"/>
    <add name="HttpPost"/>
    </protocols>
    </webServices>

    ReplyDelete
  9. If returning an array works and returning a single object doesn't, you might also try returning your single object as an array containing that single object:

    [ { title: "One", key: "1" } ]


    that way you are returning a consistent data structure, an array of objects, no matter the data payload.

    i see that you've tried wrapping your single object in "parenthesis", and suggest this with example because of course JavaScript treats [ .. ] differently than ( .. )

    ReplyDelete
  10. If jQuery's error handler is being called and the XHR object contains "parser error", that's probably a parser error coming back from the server.

    Is your multiple result scenario when you call the service without a parameter, but it's breaking when you try to supply a parameter to retrieve the single record?

    What backend are you returning this from?

    On ASMX services, for example, that's often the case when parameters are supplied to jQuery as a JSON object instead of a JSON string. If you provide jQuery an actual JSON object for its "data" parameter, it will serialize that into standard & delimited k,v pairs instead of sending it as JSON.

    ReplyDelete
  11. I found in some of my implementations I had to add:

    obj = new Object; obj = (data.obj);


    which seemed to solve the problem. Eval or not it seemed to do exactly the same for me.

    ReplyDelete
  12. Hi its good discussion I found a solution have a look here
    http://www.isolutionteam.co.uk/json-jquery-ajax-aspnet-and-c-to-get-ajaxed-data-table-rows-passing-multiple-parameters/

    ReplyDelete
  13. I had a similar problem to this where Firefox 3.5 worked fine and parsed my JSON data but Firefox 3.0.6 returned a parseerror. Turned out it was a blank space at the start of the JSON that caused Firefox 3.0.6 to throw an error. Removing the blank space fixed it

    ReplyDelete
  14. jQuery chokes on certain JSON keys. I was sending this JSON snippet in PHP:

    echo json_encode((object) array('result' => 'success'));


    Renaming the 'result' key to something else works. I would guess this is a reserved word collision of some kind, and could be a bug in jQuery (1.4.2).

    ReplyDelete
  15. In a ColdFusion environment, one thing that will cause an error, even with well-formed JSON, is having Enable Request Debugging Output turned on in the ColdFusion Administrator (under Debugging & Logging > Debug Output Settings). Debugging information will be returned with the JSON data and will thus make it invalid.

    ReplyDelete
  16. I was struggling with this, and spent a few hours trying to figure this out, until I used firebug to show the data object.

    var data = eval("(" + data.responseText + ")");
    console.log(data.count);

    ReplyDelete
  17. also try this

    $.ajax({
    url: url,
    data:datas,
    success:function(datas, textStatus, jqXHR){
    var returnedData = jQuery.parseJSON(datas.substr(datas.indexOf('{')));
    })};


    in my case server responds with unknow character before '{'

    ReplyDelete
  18. If you are echoing out the json response and your headers don't match */json then you can use the built in jQuery.parseJSON api to parse the response.

    response = '{"name":"John"}';
    var obj = jQuery.parseJSON(response);
    alert( obj.name === "John" );

    ReplyDelete
  19. Hey LiitleCharva Please help me out with d following problem which is
    very similar to the problem u asked earlier.I am sending the json
    object on php page but could able to retrieve its value Here is my
    code


    $.ajax({
    type: "POST",
    contentType: "application/json",
    data: "{eventdata:" + JSON.stringify(eventToSave) + "}",
    url: "<?php echo $base;?>/index.php/welcome/addEvent",
    dataType: "json",
    success: function (data) {
    alert("success");
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    debugger;
    }
    });



    Result in json Object


    {eventdata:{"EventID":99,"StartDate":"Thu May 10 2012 00:00:00 GMT+0530 (India Standard Time)","EndDate":"Thu May 10 2012 00:00:00 GMT+0530 (India Standard Time)","EventName":"zxzXzX"}}

    ReplyDelete