//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 lang="en">
    <head>
        <meta charset="UTF-8">
        <!--
            Change log:
                24. December 2015   -created
                30. June 2018   - reworked code for better style and clarity    - Drapak
        -->
    </head>
    <body>
	<p>
		The current data structure in this program 
		looks like this when converted to JSON:<br>
		<code id="jsonOutputID"></code>
	</p>
	
	<h4>JSON file download</h4>
	<p>
		<a id="downloadID" download="data.json">
			Click to download JSON data file
		</a>
	</p>
	
	<h4>JSON file upload</h4>
	<p>
		<!-- Use the following input line in your code. 
		It will automatically trigger the upload after the file has been chosen. -->
		<input id="fileId" type="file" >
	</p>

	<hr />     
        <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 ) {
                    // extract the information from the parameter object
                    var dataStructure       = argumentObj.dataStructure;    
                    var uploadEvent         = argumentObj.uploadEvent;
                    var callbackFunction    = argumentObj.callback;
                    
                    // only process the first file that was uploaded
                    var firstFile = uploadEvent.target.files[0];
                    // create a new file reader object to process the contents              
                    var reader = new FileReader();
                    // start reading in the file as text                    
                    reader.readAsText( firstFile );                         
                    
                    // define what to do when the file is finished being read in...
                    reader.onload = function( uploadEvent ) {   
                        // send file info to the console
                        console.log(                                             
                            "Got the file.\n" 
                            + "name: " + firstFile.name + "\n"
                            + "type: " + firstFile.type + "\n"
                            + "size: " + firstFile.size + " bytes\n"
                        );  
                        
                        // store the contents from the file
                        this.jsonString = uploadEvent.target.result;            
                        
                        //PROCESS: read the contents of the file into the data structure
                        // clear out the old dataStructure
                        dataStructure.length    = 0;                            
                        
                        // extract the data and copy over to a temporary variable
                        var tempStructure       = JSON.parse( this.jsonString );
                        
                        //LOOP: through each part of the temporary variable
                        for (i in tempStructure) {
                            // copy the temporary information into the dataStructure
                            dataStructure.push( tempStructure[ i ] );               
                        }
                        
                        // trigger the callback function when complete
                        callbackFunction();                                     
                    }
                },
                
                // 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;
                }
            };

            //OUTPUT: create the download link and display the JSON code
            var displayJSONExample = function () {
                console.log( "in displayJSONExample..." );
                
                fileTransfer.insertDownloadLink({
                    dataStructure:  students, 
                    elementID:      'downloadID'
                    }
                );
                fileTransfer.displayJSONInside( 'jsonOutputID' );
            
            }
            
            //INPUT: upload a file, transfer the data and display
            //      this is triggered whenever a file is selected in the upload box
            document.getElementById("fileId").onchange = function ( uploadEvent ) {

                fileTransfer.uploadJSONFileInto({   // read in the file     
                    // read into this data structure
                    dataStructure:  students,                   
                    // transfer in the upload data
                    uploadEvent:    uploadEvent, 
                    
                    // function to call after upload is complete
                    callback:       function () {               
                        // after the upload, display the changes to the data structure
                        displayJSONExample();       
                        } 
                    }
                );
            }
            
            //INPUT: when the page finishes loading, display the JSON example
            document.body.onload    = function () {
                displayJSONExample();
            }
        </script>
    </body>
</html>