locked
How to save json to disk - file is not flushed

    Question

  • docs = this.documents;
          return applicationData.localFolder.createFileAsync('repository', Windows.Storage.CreationCollisionOption.replaceExisting).then(function(file) {
            return file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function(stream) {
              var json, os, writer;
              os = stream.getOutputStreamAt(0);
              writer = new Windows.Storage.Streams.DataWriter(os);
              json = [];
              docs.forEach(function(item, index, all) {
                return json.push(JSON.stringify(item));
              });
              writer.writeString(json);
              return writer.storeAsync().then(function() {
                return stream.flushAsync();
              });
            });
          });
    


    This is my code, and the ~repository.tmp file contains the json but the repository file remains at 0 bytes.

    Is it really that complicated to write a JSON array to a file on disk?

    Thursday, February 02, 2012 5:47 PM

Answers

  • Nope!
    It is super simple.  You can do something like this:
     var myDataSource = [
        { title: "Banana", description: "Banana Frozen Yogurt", picture: "images/banana.jpg", isOn: true },
        { title: "Orange", description: "Orange Sherbet", picture: "images/orange.jpg", isOn: false },
        { title: "Vanilla", description: "Vanilla Ice Cream", picture: "images/vanilla.jpg", isOn: true },
        { title: "Mint", description: "Mint Gelato", picture: "images/mint.jpg", isOn: false },
        { title: "Strawberry", description: "Strawberry Sorbet", picture: "images/strawberry.jpg", isOn: true }
        ];
    
     WinJS.Application.local.writeText("json.db", JSON.stringify(myDataSource)).then(

    The key here is to not stringify each thing you push into the array, but to stringify your object.
    Then you can read it back like this:
                    WinJS.Application.local.readText("json.db").then(
                function (data) {
    
                        try {
                            basicListView = WinJS.UI.getControl(document.getElementById("basicListView"));
                            var theDb = JSON.parse(data);
                            basicListView.dataSource = theDb
    
    
                        }

    -Jeff

    Jeff Sanders (MSFT)
    Thursday, February 02, 2012 6:31 PM
    Moderator

All replies

  • Nope!
    It is super simple.  You can do something like this:
     var myDataSource = [
        { title: "Banana", description: "Banana Frozen Yogurt", picture: "images/banana.jpg", isOn: true },
        { title: "Orange", description: "Orange Sherbet", picture: "images/orange.jpg", isOn: false },
        { title: "Vanilla", description: "Vanilla Ice Cream", picture: "images/vanilla.jpg", isOn: true },
        { title: "Mint", description: "Mint Gelato", picture: "images/mint.jpg", isOn: false },
        { title: "Strawberry", description: "Strawberry Sorbet", picture: "images/strawberry.jpg", isOn: true }
        ];
    
     WinJS.Application.local.writeText("json.db", JSON.stringify(myDataSource)).then(

    The key here is to not stringify each thing you push into the array, but to stringify your object.
    Then you can read it back like this:
                    WinJS.Application.local.readText("json.db").then(
                function (data) {
    
                        try {
                            basicListView = WinJS.UI.getControl(document.getElementById("basicListView"));
                            var theDb = JSON.parse(data);
                            basicListView.dataSource = theDb
    
    
                        }

    -Jeff

    Jeff Sanders (MSFT)
    Thursday, February 02, 2012 6:31 PM
    Moderator
  • Jeff, I am speechless!

    Thanks to your and your colleagues outstanding support here we will be able to prototype our app in 3 days! In CoffeeScript no less (hope there will be support in VStudio for it in the near future).

    Our datasource is a  WinJS.Binding.List, which I think I tried to "stringify" and it did not work. Any ideas?

    Thanks a lot!


    • Edited by phil_ke Thursday, February 02, 2012 7:39 PM
    Thursday, February 02, 2012 7:37 PM
  • Hey that is awesome news Phil!!!

    You are very welcome, you new Metro style developers are awesome!

    -Jeff


    Jeff Sanders (MSFT)
    Thursday, February 02, 2012 7:38 PM
    Moderator
  • We try to get off the ground quickly and with WinJS it is really easy.

    btw: did you get my message I wrote on your MSDN blog?

    Thursday, February 02, 2012 7:42 PM
  • I tried this, and it basically works. But reading the data back results in a syntax error exception being thrown.

    And also we have no normal array but are using a WinJS.Binding.List

     

    How can I get an array of items contained in such list and how can I replace all items is such list without creating a new list?

    Friday, February 03, 2012 8:32 AM
  • If the object is not serializable you will have to come up with a scheme on your own.

    Jeff Sanders (MSFT)

    Wednesday, February 15, 2012 9:06 PM
    Moderator
  • For a WinJS.Binding.List object, you'd have to actually save out the underlying items and then put them back when you came back.  For example:

    During save:

    app.sessionState.mySavedItems = myList.slice(0); // this gets the underlying items as an array

    ...

    myList = new WinJS.Binding.List(app.sessionState.mySavedItems);


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, April 25, 2012 12:52 AM