none
"Windows.Storage.FileIO.readTextAsync(sampleFile).done" never gets called

    Question

  • Hello,

    I am following a sample about reading a text file from Storage and I am able to have the sampleFile variable correctly assigned to the wanted file (code not displayed here). When it comes to reading the file content the "done" method is never called. In the example here below I can see "A" and "B" but not "C". I see also "D" that is issued after the scenario2ReadText call has returned (code not displayed here).

    Can help? Thanks in advance.

    function scenario2ReadText() {
                document.write("<p>A</p>");
                if (sampleFile !== null) {
                    document.write("<p>B</p>");
                    Windows.Storage.FileIO.readTextAsync(sampleFile).done(function (fileContent) {
                       
                        document.write("<p>C</p>");
                        
                    });
                }
            }

    Wednesday, April 04, 2012 8:43 PM

Answers

  • There is a problem with using document.write() in your scenario.  I have not had time to study in detail but here is a modified version of your code which removes/replaces the document.write() with console.log() and calls to a "displayStatus" function that replaces the innerHTML of a div, as in:

    <div id="status">Hello</div>

    Please see my first example for displayStatus()

    And here your modified example that works:

     function readFile() {
            var fileName = "myTest.txt";
            //document.write("<p>FileName " + fileName + "</p>");
            console.log("start");
            Windows.Storage.KnownFolders.documentsLibrary.getFileAsync(fileName).done(
                function (file) {
                    var sampleFile = file;
                    //document.write("<p>File " + file.path + "</p>");
                    scenario2ReadText(sampleFile);
                   // document.write("<p>after Call " + "</p>");
                },
                function (err) {
                    console.log(err);
                    //document.write("<p>Err " + "</p>");
                    // 'sample.txt' doesn't exist so scenario one must be run
                }
            );
        }
        function scenario2ReadText(sampleFile) {
           // document.write("<p>A " + "</p>");
            if (sampleFile !== null) {
              //  document.write("<p>B " + "</p>");
                Windows.Storage.FileIO.readTextAsync(sampleFile).done(function (fileContent) {
                    displayStatus(fileContent);
                    //document.write("<p>C " + "</p>");
                    //if (index < num) { index = index + 1; fileName = basePath + fileNames[index]; initialize(); }
                });
            }
        }

    I'm not sure about using document.write for a metro app.  If I have more time, I will investigate further.

    By the way, your write "after Call" would probably execute before the read was complete because you are calling a function which has an asynchronous function.


    Thursday, April 05, 2012 6:34 PM

All replies

  • OK.  Here is a sample that works for me.  It displays the text of a file and an error message if the file is not found. 

    As written, the routine selects a named file in the documents folder.  You must set the manifest capabilities and declarations for this to work.  You can replace the Windows.Storage.KnownFolders… line with the code that has been commented out and use the FilePicker to select the file.  In this case, you don't have to set the manifest.

    function readFile() {
            displayStatus("");
    
            //Use for filePicker instead of getFileAsync the following...
            //var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
            //openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.list;
            //openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.documentsLibrary;
            //openPicker.fileTypeFilter.replaceAll([".txt"]);
            //openPicker.pickSingleFileAsync()
    
            Windows.Storage.KnownFolders.documentsLibrary.getFileAsync("myTestx.txt")
                .then(function (myFile) {
                    Windows.Storage.FileIO.readTextAsync(myFile)
                        .then(function (fileResult) {
                            displayStatus(fileResult);
                            console.log("Success");
                        });
                },
                    function (errorResult) {
                        displayStatus(errorResult);
                        console.log("Error reading ");     
                    });
        }
    
        function displayStatus(msg) {
            document.getElementById("status").innerText = msg;
        }

    ****Edit: The previous example nested two promises.  Here is an alternate portion of the code with the two promises chained as recommended.

    Windows.Storage.KnownFolders.documentsLibrary.getFileAsync("myTest.txt")
                .then(function (myFile) { return Windows.Storage.FileIO.readTextAsync(myFile); })
                .done(function (fileResult) {
                    displayStatus(fileResult);
                    console.log("Success");
                },
                function (errorResult) {
                    displayStatus(errorResult);
                    console.log("Error reading ");
                });


    Thursday, April 05, 2012 3:38 AM
  • Thank you. But if I replace "done" with "then" I read not "A", "B","C" or "D". The same if I replace "done" with "ten","thn". I think the Javascript runs into an error.
    Thursday, April 05, 2012 7:27 AM
  • I think you may have a javascript runtime error that you are not seeing due to the way errors in promises are handled.

    Try to follow the advice in the topic: How to handle errors when using promises in Javascript.

    It suggests to select Thrown for Javascript Runtime Exceptions in the Debug > Exceptions menu and run in Debug mode (the default).  This should expose the error that is causing your code to fail.

    Thursday, April 05, 2012 10:05 AM
  • I set the debugger to throw Javascript exceptions but they are not thrown when expected to, that is when I cannot see "B" and so on. What else have I to set to see the exceptions or what's going wrong there?

    Edit: I have two functions that call each other and the call happens just inside the functions passed in "done" of getFileAsync and readTextAsync , could it be the reason for my app not working?

    • Edited by P5music Thursday, April 05, 2012 3:45 PM
    Thursday, April 05, 2012 3:38 PM
  • It might be helpful if you would post more of your code (that is, the two functions that are calling each other.)

    Does the information in the exception message offer any clues?

    Thursday, April 05, 2012 4:03 PM
  • There is other code that starts everything, but these are the two functions:

    function initialize() {
                document.write("<p>FileName "+fileName+"</p>");
                Windows.Storage.KnownFolders.documentsLibrary.getFileAsync(fileName).done(
                function (file) {
                    sampleFile = file;
                    document.write("<p>File " + file.path + "</p>");
                    scenario2ReadText();
                    document.write("<p>after Call " +"</p>");
                },
                function (err) {
                    document.write("<p>Err " + "</p>");
                    // 'sample.txt' doesn't exist so scenario one must be run
                }
            );
            }
            function scenario2ReadText() {
                document.write("<p>A " + "</p>");
                if (sampleFile !== null) {
                    document.write("<p>B "  + "</p>");
                    Windows.Storage.FileIO.readTextAsync(sampleFile).done(function (fileContent) {
                       
                        document.write("<p>C " + "</p>");
                        if (index < num) { index = index + 1; fileName = basePath + fileNames[index]; initialize(); }
                    });
                }
            }
    Once I was able to see also "C", so could it be a problem of timing?

    Thursday, April 05, 2012 5:03 PM
  • There is a problem with using document.write() in your scenario.  I have not had time to study in detail but here is a modified version of your code which removes/replaces the document.write() with console.log() and calls to a "displayStatus" function that replaces the innerHTML of a div, as in:

    <div id="status">Hello</div>

    Please see my first example for displayStatus()

    And here your modified example that works:

     function readFile() {
            var fileName = "myTest.txt";
            //document.write("<p>FileName " + fileName + "</p>");
            console.log("start");
            Windows.Storage.KnownFolders.documentsLibrary.getFileAsync(fileName).done(
                function (file) {
                    var sampleFile = file;
                    //document.write("<p>File " + file.path + "</p>");
                    scenario2ReadText(sampleFile);
                   // document.write("<p>after Call " + "</p>");
                },
                function (err) {
                    console.log(err);
                    //document.write("<p>Err " + "</p>");
                    // 'sample.txt' doesn't exist so scenario one must be run
                }
            );
        }
        function scenario2ReadText(sampleFile) {
           // document.write("<p>A " + "</p>");
            if (sampleFile !== null) {
              //  document.write("<p>B " + "</p>");
                Windows.Storage.FileIO.readTextAsync(sampleFile).done(function (fileContent) {
                    displayStatus(fileContent);
                    //document.write("<p>C " + "</p>");
                    //if (index < num) { index = index + 1; fileName = basePath + fileNames[index]; initialize(); }
                });
            }
        }

    I'm not sure about using document.write for a metro app.  If I have more time, I will investigate further.

    By the way, your write "after Call" would probably execute before the read was complete because you are calling a function which has an asynchronous function.


    Thursday, April 05, 2012 6:34 PM