//SOLVE: Saving and opening data files using JSON

Transferring data using object-oriented Javascript

Sometimes you want to save and open data. This happens less in web programming, but it still happens a lot.

JSON (JavaScript Object Notation), is a way to print out and read in data structures easily into Javascript.

The current data structure in this program looks like this when converted to JSON:

JSON file download

The JSON information can be stored inside a data URL. When the user clicks on the link, the browser converts the data into a file with the same name that is given inside the download part of the link. Hover over the link and check out the status bar to see what this link looks like.

Click to download JSON data file

JSON file upload

JSON data files can also be read into Javascript using the built-in FileReader capabilities.

Please select the data file to upload. This file should be a JSON text file.
(Try editting a saved JSON file and upload the results to see the data structure change above...)


Learn more

Source code

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Uploading and downloading data using object-oriented Javascript</title>        
        <script>
            // INIT: initialize a data structure that we can save and open later
            var students = [
                {   givenName:  "Devon",
                    familyName: "Frisk",
                    mark:       78          },
                {   givenName:  "Jamie",
                    familyName: "Beals",
                    mark:       67          },
                {   givenName:  "Adrien",
                    familyName: "Petrivitch",
                    mark:       92          },
                {   givenName:  "MacKenzie",
                    familyName: "Li",
                    mark:       63          }
            ]; 
            
            // fileTransfer OBJECT
            // 
            //  properties: 
            //      fileTransfer.jsonString
            //
            //  methods:
            //      fileTransfer.uploadJSONFileInto( { dataStructure: ... , uploadEvent: ..., callback: function() {...} } )
            //      fileTransfer.insertDownloadLink( { dataStructure: ... , elementID: ... } )
            //      fileTransfer.displayJSONInside( elementID )
            //
            var fileTransfer = {
                jsonString:     null,
                
                // INPUT: upload the file and store as this.jsonString
                uploadJSONFileInto: function ( argumentObj ) {
                    var dataStructure       = argumentObj.dataStructure;    // extract the information from the parameter object
                    var uploadEvent         = argumentObj.uploadEvent;
                    var callbackFunction    = argumentObj.callback;
                    
                    var firstFile = uploadEvent.target.files[0];            // only process the first file that was uploaded
                    var reader = new FileReader();                          // create a new file reader object to process the contents
                    reader.readAsText( firstFile );                         // start reading in the file as text
                    
                    reader.onload = function( uploadEvent ) {               // define what to do when the file is finished being read in...
                        console.log(                                            // send file info to the console 
                            "Got the file.\n" 
                            + "name: " + firstFile.name + "\n"
                            + "type: " + firstFile.type + "\n"
                            + "size: " + firstFile.size + " bytes\n"
                        );  
                        
                        this.jsonString = uploadEvent.target.result;            // store the contents from the file
                        
                        //PROCESS: read the contents of the file into the data structure
                        dataStructure.length    = 0;                            // clear out the old dataStructure
                        
                        var tempStructure       = JSON.parse( this.jsonString );// extract the data and copy over to a temporary variable
                        for (i in tempStructure) {                              // loop through each part of the temporary variable
                            dataStructure.push( tempStructure[ i ] );               // copy the temporary information into the dataStructure
                        }

                        callbackFunction();                                     // trigger the callback function when complete
                    }
                },
                
                // PROCESS+OUTPUT: this creates a download link in #elementID of the dataStructure in JSON format
                insertDownloadLink: function ( argumentObj ) {
                    var dataStructure   = argumentObj.dataStructure;
                    var elementID       = argumentObj.elementID;
                    
                    //PROCESS: convert the dataStructure to JSON
                    this.jsonString     = JSON.stringify( dataStructure );
                    
                    //PROCESS: create a data URL from the JSON code
                    var dataURL         = "data:text/json;charset=utf-8," + encodeURIComponent( this.jsonString );
                    
                    //OUTPUT: insert the data URL into the output link
                    document.getElementById( elementID ).href       = dataURL;
                },
                                
                // OUTPUT: display the data structure inside a given id
                displayJSONInside:    function ( elementID ) {
                    document.getElementById( elementID ).innerHTML  = this.jsonString;
                }
            };

            // Create a JSON string based on students and display
            // This is triggered when the page loads
            var displayJSONExample = function () {
                fileTransfer.insertDownloadLink({
                    dataStructure:  students, 
                    elementID:      'downloadID'
                    }
                );
                fileTransfer.displayJSONInside( 'jsonOutputID' );
            }
            
            // upload a file, transfer the data and display
            // this is triggered whenever a file is selected in the upload box
            var uploadFile = function ( uploadEvent ) {
                fileTransfer.uploadJSONFileInto({           // read in the file
                    dataStructure:  students,                   // read into this data structure
                    uploadEvent:    uploadEvent,                // transfer in the upload data
                    callback:       function () {               // function to call after upload is complete
                                        displayJSONExample();       // after the upload, display the changes to the data structure
                                    } 
                    }
                );
            }
        </script>
        <style>
        </style>
    </head>
    <body onload="displayJSONExample();">
        
        <h4>
            Current data structure: 
        </h4>
        
        <code id="jsonOutputID"></code>

        <p>
            <a id="downloadID" download="data.json">
                Click to download JSON data file
            </a>
        </p>
        
        <h4>JSON file upload</h4>
        <p>
            Please select the data file to upload.<br />
            This file should be a JSON text file.     
        </p>
        <!-- Use the following input line in your code. It will automatically trigger the upload after the file has been chosen. -->
        <input 
            type="file" 
            name="files[]" 
            onchange="uploadFile( event );" />
    </body>
</html>