2

This question is related to a previous one I wrote here.

Is this JSON syntax correct ? I need it to make a jqPlot chart after.

[{"Date":"2012-02-29","Close":"87.60"},{"Date":"2012-02-28","Close":"87.77"},{"Date":"2012-02-27","Close":"88.07"}]

I ask this because I can't use jQuery.parseJSON(jsonString); or JSON.parse(jsonString); with this string. Firefox returns :

SyntaxError: JSON.parse: unexpected character @ index2.php:677


Here is the PHP code that generates it :

<?php
    $req = $bdd->prepare('SELECT Date, Close FROM quotes WHERE Symbol = ? AND Date > ? AND Date < ?');
    $req->execute(array($_GET['id'], $_GET['datemin'], $_GET['datemax']));

    $test=array();
    while ($donnees = $req->fetch(PDO::FETCH_ASSOC))
    {
        // echo print_r($donnees) . "<br />";
        // echo $donnees[Date] . "<br />";
        $test[] = $donnees;
    }

    echo json_encode($test);
?>

I don't know what's wrong.



EDIT : Javascript code added.

<script>
$("button").click(function(){
    $.get("requete_graph.php", {
        id: param1,
        datemin: param2,
        datemax: param3
    }, function(data,status){
        console.log(data);
        make_graph(data);
    }, "json");
}); 

function make_graph(toto) {
    alert("String before : " + JSON.stringify(toto));
    var json_parsed = JSON.parse(toto);
    alert("String after : " + JSON.stringify(json_parsed));

    $(document).ready(function(){
        var plot1 = $.jqplot('chartdiv', json_parsed);
    });
}
</script>
Community
  • 1
  • 1
pihug12
  • 317
  • 3
  • 14
  • 4
    Show us that `JSON.parse` call! Your JSON seems to be valid, maybe you unexpectedly did echo some other characters around it. – Bergi Jun 04 '13 at 17:35
  • 1
    it is valid. In the future consider using http://jsonlint.com/ to check. However it will only be parseable if its passed as a javascript string. – Ben McCormick Jun 04 '13 at 17:35
  • You probably need to encode the json like `$test[] = utf8_encode($donnes);` or something. I mean just going on what you've provided - I'm reaching... – crush Jun 04 '13 at 17:35
  • 1
    The JSON we see is correct. Are you sure there isn't nothing more ? Did you look at the result in the browser ? – Denys Séguret Jun 04 '13 at 17:35
  • 1
    @crush Don't randomly apply `utf8_encode`, especially if the data doesn't even contain any non-ASCII characters. – deceze Jun 04 '13 at 17:45
  • @deceze I don't know that they don't. There is nothing wrong with the code he gave us. It's clearly in another language, so I'm assuming that he didn't give us all of the code/output. Like I said, I'm just taking shots in the dark considering the lack of information. – crush Jun 04 '13 at 17:46
  • @crush 1) You don't know what encoding the text is in to begin with, 2) if it wasn't valid UTF-8, `json_encode` would not encode it, 3) the values are apparently only dates and numbers, 4) read [What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text](http://kunststube.net/encoding/) – deceze Jun 04 '13 at 17:47
  • I agree with Bergi, show us the code around `JSON.parse` / `jQuery.parseJSON`. I suspect you're retrieving this in an AJAX call, which jQuery will decode for you - no need to call `parse` manually. – Izkata Jun 04 '13 at 17:48
  • Make sure none of your PHP files have Byte Order Marks. http://stackoverflow.com/questions/4740973/why-doesnt-jquery-parsejson-work-on-all-servers http://stackoverflow.com/questions/6066901/invalid-json-in-chrome-no-problem-in-firefox-so-strange http://stackoverflow.com/questions/8028957/headers-already-sent-by-php – PleaseStand Jun 04 '13 at 17:49
  • @deceze PHP default encoding is ISO-8859-1, not UTF-8. `json_encode` WILL in fact, attempt to encode non UTF-8. There ARE in fact Q&A here on SO that deal with this fact. – crush Jun 04 '13 at 17:52
  • @crush What does "PHP default encoding" mean? And no, `json_encode` *fails* outright when trying to encode anything but UTF-8: http://3v4l.org/2RRTN – deceze Jun 04 '13 at 17:54
  • I added the JavaScript code. My PHP files are UTF-8 encoded. I don't know if it's related. – pihug12 Jun 04 '13 at 18:04
  • 3
    `data` and thereby `toto` should be *objects*, not JSON strings. Why are you `parsing` `toto`? – deceze Jun 04 '13 at 18:06
  • @deceze Thanks for the article, but this contains information I already knew. What I didn't know was that PHP's json_encode would fail if to encode non-UTF-8 characters. I remembered incorrectly another issue on SO, and thought the opposite behavior was true. – crush Jun 04 '13 at 18:20
  • Probably not related, but... why do you have `$(document).ready(function(){...}` inside a function?? – Marcelo Pascual Jun 04 '13 at 18:27
  • @MarceloPascual You're right that it doesn't make sense. He is binding that event handler after the function has been called, but at that time, the `.ready()` event has already fired anyways. – crush Jun 04 '13 at 18:28
  • Also @deceze http://php.net/manual/en/xml.encoding.php "The default source encoding used by PHP is ISO-8859-1" Which is where the myth seems to have perpetuated from, but as you can see, this only deals with XML documents. – crush Jun 04 '13 at 18:30
  • @deceze : I wanted to do this because I need a string like that `[[['2012-02-29', 87.60],['2012-02-28', 87.77],['2012-02-27', 88.07]]]` to use jqPlot. I'm not sure how to do that. @MarceloPascual : I wasn't sure is this was useful or not, I will remove it. – pihug12 Jun 04 '13 at 18:36
  • 1
    You have `, "json"` in your `$.get` call. This means jQuery is parsing the JSON for you. `data`, and therefore `toto` is *already* an object/array. – gen_Eric Jun 04 '13 at 18:48
  • OK. But I don't get how I can transform this array into a string. `alert(toto)` returns `[object Object],[object Object],[object Object]`. And `alert(JSON.stringify(toto))` returns the JSON format (`[{"Date":"2012-02-29","Close":"87.60"},{"Date":"2012-02-28","Close":"87.77"},{"Date":"2012-02-27","Close":"88.07"}]`). What do I have to do to make a string like this `[[['2012-02-29', 87.60],['2012-02-28', 87.77],['2012-02-27', 88.07]]]` ? – pihug12 Jun 04 '13 at 19:04
  • You're gonna need to loop through `toto` and build that array yourself. – gen_Eric Jun 04 '13 at 19:31

3 Answers3

0

The JSON is indeed valid (you can check it at jsonlint.com

Your problem might be arising due to extra non whitespace characters being sent after the JSON (for example: PHP errors/warnings). A good way to guarantee that nothing else is output after your JSON is using PHP's die function to send content then stop executing.

die(json_encode($test));

// OR
echo json_encode($test);
die();
clinton3141
  • 4,751
  • 3
  • 33
  • 46
  • I don't see any extra characters being sent after the JSON is echo'd. I see a PHP closing tag that doesn't need to be there, but extra white space won't invalidate his JSON. – crush Jun 04 '13 at 17:54
  • @crush I meant extra bits like PHP errors or warnings - I'll update my answer to clarify. – clinton3141 Jun 04 '13 at 17:55
0

At the top of your PHP script, add:

header('Content-type: text/json; charset=utf-8');

If you don't have it, the server will send it as plain text, and your browser won't know that it is a json string.

Marcelo Pascual
  • 810
  • 8
  • 20
  • 3
    I prefer [`application/json`](http://stackoverflow.com/questions/477816/what-is-the-correct-json-content-type) myself. – crush Jun 04 '13 at 18:16
  • Also, I don't think this would solve the OP's problem. The comment that @deceze suggested above is the issue. – crush Jun 04 '13 at 18:20
0

jQuery.get, given the right dataType parameter (which you did) or a content-type header, does already parse the JSON for you. Your callback function receives an array as the data parameter, not a string.

var json_parsed = JSON.parse(toto);

will then throw an error as toto is not a JSON string (your FF seems to .toString() the array, and then encounters and invalid character). Instead, just use

function make_graph(toto) {
    console.log(typeof toto, toto);
    alert("String before : " + JSON.stringify(toto));
    var json_parsed = toto; // or just use `toto` everywhere

    $(document).ready(function(){
        var plot1 = $.jqplot('chartdiv', json_parsed);
    });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375