views:

79

answers:

2

I'm trying to write my JSON object to a .json file on the server. The way I'm doing this now is:

JavaScript:

function createJsonFile() {

    var jsonObject = {
        "metros" : [],
        "routes" : []
    };

    // write cities to JSON Object
    for ( var index = 0; index < graph.getVerticies().length; index++) {
        jsonObject.metros[index] = JSON.stringify(graph.getVertex(index).getData());
    }

    // write routes to JSON Object
    for ( var index = 0; index < graph.getEdges().length; index++) {
        jsonObject.routes[index] = JSON.stringify(graph.getEdge(index));
    }

    // some jQuery to write to file
    $.ajax({
        type : "POST",
        url : "json.php",
        dataType : 'json',
        data : {
            json : jsonObject
        }
    });
};

PHP:

<?php
   $json = $_POST['json'];
   $info = json_encode($json);

   $file = fopen('new_map_data.json','w+');
   fwrite($file, $info);
   fclose($file);
?>

It is writing fine and the information seems to be correct, but it is not rendering properly. It is coming out as:

{"metros":["{\\\"code\\\":\\\"SCL\\\",\\\"name\\\":\\\"Santiago\\\",\\\"country\\\":\\\"CL\\\",\\\"continent\\\":\\\"South America\\\",\\\"timezone\\\":-4,\\\"coordinates\\\":{\\\"S\\\":33,\\\"W\\\":71},\\\"population\\\":6000000,\\\"region\\\":1}",

... but I'm expecting this:

"metros" : [
    {
        "code" : "SCL" ,
        "name" : "Santiago" ,
        "country" : "CL" ,
        "continent" : "South America" ,
        "timezone" : -4 ,
        "coordinates" : {"S" : 33, "W" : 71} ,
        "population" : 6000000 ,
        "region" : 1
    } ,

Any idea why I'm getting all of these slashes and why it is all on one line?

Thanks, Hristo

+3  A: 

Hi,

Don't JSON.stringify. You get a double JSON encoding by doing that.

You first convert your array elements to a JSON string, then you add them to your full object, and then you encode your big object, but when encoding the elements already encoded are treated as simple strings so all the special chars are escaped. You need to have one big object and encode it just once. The encoder will take care of the children.

For the on row problem try sending a JSON data type header: Content-type: text/json I think (didn't google for it). But rendering will depend only on your browser. Also it may be possible to encode with indentation.

Alin Purcaru
I guess that worked... I thought I need to do `JSON.stringify` so that it formats my object properly? I defined a `toJSON` function for my object so that is why i was using `stringify`. I took it out and it got rid of the \\\ but it is still all on one line...
Hristo
@Hristo: What's wrong with all of it being on one line? I don't think you should care.
Tomalak
He may need to check if while in development and this might help him. If it's just for storing there's nothing wrong.
Alin Purcaru
http://www.jsonlint.com/ does that better than visually scanning a formatted string.
Tomalak
+3  A: 

You are double-encoding. There is no need to encode in JS and PHP, just do it on one side, and just do it once.

// write cities to JSON Object
for ( var index = 0; index < graph.getVerticies().length; index++) {
    /* do not yet convert to JSON here */
    jsonObject.metros[index] = graph.getVertex(index).getData();
}

// write routes to JSON Object
for ( var index = 0; index < graph.getEdges().length; index++) {
    /* do not yet convert to JSON here */
    jsonObject.routes[index] = graph.getEdge(index);
}

// some jQuery to write to file
$.ajax({
    type : "POST",
    url : "json.php",
    dataType : 'json', 
    data : {
        json : JSON.stringify(jsonObject) /* convert here only */
    }
});

Note that the dataType parameter denotes the expected response type, instead of the type you send the data with. Post requests will always be sent as application/x-www-form-urlencoded. I don't think you need that parameter at all, unless you expect a JSON response and want to do something with it (i.e. via the onsuccess event handler). You could even trim that down to:

$.post("json.php", {json : JSON.stringify(jsonObject)});

Then (in PHP) do:

<?php
   $json = $_POST['json'];

   if (json_decode($json) != null) { /* sanity check */
     $file = fopen('new_map_data.json','w+');
     fwrite($file, $info);
     fclose($file);
   } else {
     // handle error 
   }
?>
Tomalak