Working with JSON

JSON is a format close to GreyCat objects and arrays. It is therefore quite easy to manipulate JSON files.

Read

This section presents how to get a JSON representation from String or File, and how to read the contents. To be noted, in contrast with other types of files, the JSON format only partially allows streaming the content (reading byte by byte). Indeed, JSON Objects and Arrays are blocks that need to be loaded at once.
The JsonReader however allows to read, in sequence, several JSON elements that have been serialized in a file, with or without new lines to separate them. We therefore recommend concatenating several small JSON elements in a signe file to save performances, rather than one huge element, or several small files.

Read File

The JsonReader will provide the tools to read through the JSON file. The read() function will read the content of the file, element by element. That is, if the first element in your JSON file is an array, it will read and return this array. Likewise, if the first element is an object, it will read the object fully and return it.

fn run() {
    var reader = JsonReader::new("data/myData.json");
    while(reader.available() > 0) {
        var parsedArray = reader.read() as Array;
    }
}

Files are automatically closed when leaving the function where they were opened. If files are written then read in the same function, setting the Writer or Reader to null closes and flushes the contents to disk.

If your file contains several elements concatenated, you can use a loop to read the contents until available() returns 0 (i.e. no more bytes to read).

GreyCat will load the content of JSON with the correct types (int, float, Object, Array, bool, null, String). The result of the read(): any? function can therefore be casted to the expected type, provided that the data in your file conforms to the specifications consistently.
The cast will otherwise throw an exception that you can deal with.

Parse String

In a quite similar way, it is possible to parse a String, obtained for instance as a result of an API HTTP call.

var parsedResult = JsonReader::parse(contentFromAPI as String);

Read arrays

To read a JSON array, you can simply use a for loop as follows. Here again, the arrayElement will have a type any, but you can safely cast to int if you expect an array of intergers, etc.

for(position, arrayElement in parsedArray) {
    //Do some with arrayElement
}

Read objects

To read a JSON object, can get the values of its properties by using get(propName: String): any?. The function returns a nullable any, that can be casted to the expected type (if not null).

var firstName = jsonObject.get("first_name") as String;

Can we iterate over the object properties with a for loop ?

Write

The JsonWriter will help you serialize GreyCat elemnts into a JSON formated file.

You first need to create a JsonWriter and give it the path of the file you want to write into as parameter.
Two versions of the JsonWriter are available. One that will override any existing file; the second that will append to the content of an existing file.

fn run() {
    //Overriding writer
    var writer = JsonWriter::new("./myFile.json");

    //Appending writer
    var writer = JsonWriter::new_append("./myFile.json");
}

You can then use write(elem: any?) or writeln(elem: any?) to write a GreyCat element into the file as JSON format. You can write Arrays, Objects, and primitive types.

fn run() {
    [...]
    //Without new line
    writer.write({name: "John", age: 42});

    //With new line
    writer.writeln([true, false, null]);
}