Storage not working, HELP

Hi there,
I am trying the Storage Module and it seems not to work. The console logs that the file has been saved by showing the token - this event happens after the user inputs the new string and clicks a button. But when I try to read from the same file, the JSON parsed is NULL.

The idea : The user inputs a string or sentence which is saved as an object such as { id : ‘id’, data : ‘data’, time : ‘time’ }. When the data is fetched, I would like it to fetches all the saved strings as a JSON, such as { wholedata : [ { id : 'id', data : 'data', time : 'time' }, { id : 'id', data : 'data', time : 'time' } ]} so that I can loop through and update the observable that is also updating the UX.

Here is the JavaScript code:

// The constants
var Observable = require("FuseJS/Observable");
var Storage = require("FuseJS/Storage");
var SAVENAME = "nau.txt";
var r_date = new Date();

// Variables
var data = Observable();
var save_new = Observable("");

function getdata() {
	// Get the data from the file
	Storage.read(SAVENAME).then(
		// First function if successful
		function(content) {
			var read_data = JSON.parse(content);

			// Save the data in variable, if there is data
			if( read_data.wholedata.length > 0 ) {
				for( var i = 0; i < read_data.wholedata.length; ++i  ) {
					data.add( {
						counter : read_data.wholedata[i].counter,
						data : read_data.wholedata[i].data,
						date : read_data.wholedata[i].date
					});
				}
			}else {
				console.log('No data to read ' + read_data.wholedata.length);
			}
		},

		// Second function if not sucessful
		function(error) {
			console.log(error)
		}
	);
}
// Run getdata on initialize
getdata();

function savenew() {
	// Get the value to store in the storage file
	var counter_to_store = data.length + 1;
	var data_to_store = save_new.value;
	var date_to_store = r_date.toDateString() + " - " + r_date.getHours() + ":" + r_date.getMinutes() + ":" + r_date.getSeconds();

	// Save data in variable
	data.add({
		counter : counter_to_store,
		data : data_to_store,
		date : date_to_store
	});

	// Save in file
	var storeObject = { wholedata : data.value };
    Storage.write(SAVENAME, JSON.stringify(storeObject)).then(
    	function(wasSuccess) {
    		if(wasSuccess) {
    			Storage.read(SAVENAME).then( 
    				function(content) {
    					var storedToken = content;
    					console.log('token = ' + storedToken ); 
    				}
    			);
    		}
    	}
    );
}

Thanks in advance for the help.

Hi Brian,

first of all, FileSystem is preferred over Storage. Aside from that, Storage totally works; it’s a problem with the logic in your code. In particular, this line isn’t how you should be treating an observable list:

var storeObject = { wholedata : data.value };

there, you’re essentially only ever reading the first item in the list, which I’m sure isn’t what you wanted.

Here’s a complete, minimal, fully working example of doing what you were after:

<App>
    <JavaScript>
        var Observable = require("FuseJS/Observable");
        var FileSystem = require("FuseJS/FileSystem");

        var path = FileSystem.dataDirectory + "/" + "mydata.json";
        var data = Observable(); // data is going to be an observable list
        var inputString = Observable(""); // inputString is just an observable string

        function read() {
            // check if file exists, and if not, create it with an empty array string representation
            if (!FileSystem.existsSync(path)) writeStringToFile("[]");
            // and then, read the file and update data observable with the array of items
            FileSystem.readTextFromFile(path).then(function(str) {
                var arr = JSON.parse(str);
                console.log("read data, length: " + arr.length);
                data.replaceAll(arr);
            });
        }

        // save function creates a string representation of array
        // that is taken from the data observable list
        // and then calls the function that does the actual saving to file
        function save() {
            writeStringToFile(JSON.stringify(data.toArray()));
        }

        // since we're only storing string contents, let's have a function for that
        function writeStringToFile(str) {
            FileSystem.writeTextToFile(path, str).then(function() {
                console.log("saved");
                // we do not need to call read() again, because the data observable
                // holds the latest data already anyway
            }).catch(function(e) {
                console.log("not saved: " + e);
            });
        }

        // when user hits enter in UI, we add the item to the data observable
        // then clear the text input value
        // and save the now-modified list to file
        function addItem() {
            data.insertAt(0, inputString.value);
            inputString.value = "";
            save();
        }

        // just for testing, we also have a way to clear the saved data
        // where "clearing" is writing an empty array string representation to the file
        function clear() {
            writeStringToFile("[]");
            // we could just call data.clear() now, but since we're lazy
            // and we know that read() will update the data observable,
            // we can just call read() here
            read();
        }

        // on app init, read the file
        read();

        module.exports = {
            data: data,
            addItem: addItem,
            inputString: inputString,
            clear: clear
        };
    </JavaScript>

    <ClientPanel>
        <Panel Height="56" Dock="Top" Color="#f81">
            <TextInput Value="{inputString}" Height="56" TextColor="#fff" Margin="4">
                <TextInputActionTriggered>
                    <Callback Handler="{addItem}" />
                </TextInputActionTriggered>
            </TextInput>
        </Panel>
        <Panel Height="56" Dock="Bottom" Color="#81f" Clicked="{clear}">
            <Text Value="Clear saved" Color="#fff" Alignment="Center" />
        </Panel>
        <ScrollView>
            <StackPanel Margin="4" ItemSpacing="2">
                <Each Items="{data}">
                    <Panel Height="56">
                        <Text Value="{}" Color="#fff" Alignment="Center" />
                        <Rectangle Color="#18f" CornerRadius="2" />
                    </Panel>
                </Each>
            </StackPanel>
        </ScrollView>
    </ClientPanel>
</App>

Hi there,

Thanks for your input. I made the necessary changes and it’s working perfectly.

Thanks for your continuous feedback and help. Fuse rocks!