locked
File IO problem in roamingFolder - How to store and retrieve app data?

    Question

  •    I'm trying to store few user data into a roamingFolder method/property of Windows Storage in an app using JavaScript. I'm following a sample code from the Dev Center, but no success. My code snippet is as follows : (OR SkyDrive link for the full project : https://skydrive.live.com/redir?resid=F4CAEFCD620982EB!105&authkey=!AE-ziM-BLJuYj7A )

    filesReadCounter: function() {
        roamingFolder.getFileAsync(filename)
            .then(function (filename) {
                return Windows.Storage.FileIO.readTextAsync(filename);
            }).done(function (data) {
                var dataToRead = JSON.parse(data);
                var dataNumber = dataToRead.count;
                var message = "Your Saved Conversions";
                //for (var i = 0; i < dataNumber; i++) {
                message += dataToRead.result;
                document.getElementById("savedOutput1").innerText = message;
                //}
                //counter = parseInt(text);
                //document.getElementById("savedOutput2").innerText = dataToRead.counter;
            }, function () {
                // getFileAsync or readTextAsync failed.
                //document.getElementById("savedOutput2").innerText = "Counter: <not found>";
            });
    },
    
      filesDisplayOutput: function () {
        this.filesReadCounter();
    }
         I'm calling filesDisplayOutput function inside ready method of navigator template's item.js file, to retrieve last session's data. But it always shows blank. I want to save upto 5 data a user may need to save.  
    Wednesday, March 13, 2013 6:37 PM

Answers

  • To keep appending to a file you need to do two things:

    1.) roamingFolder.createFileAsync(filename, Windows.Storage.CreationCollisionOption.openIfExists)

    2.) return Windows.Storage.FileIO.appendTextAsync(filename, savedData);

    Additonally when saving an array of objects as a JSON, you need to use the following format in Sample.txt to not run into parsing errors:

    [{"result":"\"21 inches = 21 inches\"","count":1},{"result":"\"32 inches = 32 inches\"","count":2}]

    Thx,

    Prashant

    Friday, March 15, 2013 6:42 PM
    Moderator

All replies

  • Sonal,

    I am seeing the problem only when I enter a value in the textbox and then click "Save" directly. However, if I type in a number in the textbox, move focus outside the textbox (by clicking somewhere else other than the save button) and then then click the button to save values, the values get stored in the sampleFile.txt file that resides in:

    C:\Users\<username>\AppData\Local\Packages\3c1f4209-ad7c-4e4a-b3e7-3a0cd45fc827_j6b59mrq6axnt\RoamingState folder.

    What is happening is that your input box has the 'change' function declared, so when you directly click the 'Save' button, the change handler for the input box gets invoked, and not saveBtnClicked. This is normal, since the input box' change handler is getting triggered first as expected. What you should consider is to disable the button when there is no input and only enable the save button when the input is legitimate. This will give the user the right impression when he/she should click the Save button to get the correct functionality.

    Thanks,

    Prashant.

    Thursday, March 14, 2013 12:27 AM
    Moderator
  •  Hi Prashant,

    Thanks again. I tried to do as your suggestion. Now the problem is that my program saves only one data. Is it something that

    Windows.Storage.FileIO.writeTextAsync(filename, savedData); opens up a new file every time? I want to append data each time a user clicks the save button. What I see is when I run my program and click "save" button more than one time, it increments the counter. But If I close the app and run it again, it only shows the last data saved. So what can I do?

    Thursday, March 14, 2013 6:32 PM
  • To keep appending to a file you need to do two things:

    1.) roamingFolder.createFileAsync(filename, Windows.Storage.CreationCollisionOption.openIfExists)

    2.) return Windows.Storage.FileIO.appendTextAsync(filename, savedData);

    Additonally when saving an array of objects as a JSON, you need to use the following format in Sample.txt to not run into parsing errors:

    [{"result":"\"21 inches = 21 inches\"","count":1},{"result":"\"32 inches = 32 inches\"","count":2}]

    Thx,

    Prashant

    Friday, March 15, 2013 6:42 PM
    Moderator
  • I tried following approach, but still not getting the end result. I'm storing json data into an array, but each time the save button is clicked a new array is saved into the file. It creates parsing problem. What is the right method to solve this problem of saving data into a text file?

    var dataArray = new Array();

    saveBtnClicked: function(eventInfo) { var saveButton = document.getElementById("saveBtn"); var that = this; roamingFolder.createFileAsync(filename, Windows.Storage.CreationCollisionOption.openIfExists) .then(function (filename) { //original, single json object var dataToSave = { "result": '"' + toLength.innerText +'"', "count": counter }; dataArray[counter] = dataToSave; counter = counter + 1; var savedData = JSON.stringify(dataArray); console.log(savedData); return Windows.Storage.FileIO.appendTextAsync(filename, dataArray); //return Windows.Storage.FileIO.writeTextAsync(filename, savedData); }).done(function () { that.filesDisplayOutput(); }); }, //End of saveBtn filesReadCounter: function() { roamingFolder.getFileAsync(filename) .then(function (filename) { return Windows.Storage.FileIO.readTextAsync(filename); }).done(function (data) { var dataToRead = JSON.parse(data); console.log(dataToRead); var message = "Your Saved Conversions : "; message += dataToRead.result; document.getElementById("savedOutput1").innerText = message; }, function () { // getFileAsync or readTextAsync failed. //document.getElementById("savedOutput2").innerText = "Counter: <not found>"; }); },



    • Edited by SonalMac Tuesday, March 19, 2013 9:04 AM
    Tuesday, March 19, 2013 9:03 AM
  • What exactly do you want to do? Do you want your app to "retain" the values regardless of whether it starts afresh or do you want to only save values per "session" - meaning that your app will remember values only for that instance and when the app stops and the new app is launched, the file will have new values?

    If you want to retain the values across multiple instances, then you can populate the dataArray everytime you read from the file.

    Tuesday, March 19, 2013 4:59 PM
    Moderator
  •   Yes, I want to retain the values across multiple instances. When I try to parse incoming data into filesReadCounter function, the data comes in this format : [ { result: "text", count: 0}] [ {result:"text", count: 0}, {result:"text", count: 1}] .   I know that I've some problem saving objects in the array and then appending it to file.

    So, it's not able to populate the dataArray when reading the file, because it gives parsing array.

    Tuesday, March 19, 2013 7:46 PM