0

I'm using cordova-plugin-file to write a text file. I can get the plugin to populate a <div> on a modal popup. This snippet works perfectly:

function readFile6(fileName){
        var str = '';
        window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(dir){
        dir.getFile(fileName, {create: false}, function(fileEntry){

            fileEntry.file(function(file){
                var reader = new FileReader();
                reader.onloadend = function (evt) {
                   $(".accordine").html(evt.target.result);
                };
                reader.readAsText(file);

            }, function(error){
                alert("Error: " + error.code);
            });
        }, function(error){
            alert("Error: " + error.code);
        });
}, function(){
    alert("Error");
});

Problem is, I need the content of the file to be returned to the calling function so I can manipulate the data before it is displayed.

I read every tutorial/sample I can find, but none of the examples shows how to do anything with the contents except populate a div or show in console.log().

How can I get the text file's contents as a return value?

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Ed Tiley
  • 13
  • 6
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Paul Roub Jan 16 '17 at 21:45
  • This isn't AJAX. The data I need is right there in evt.target.result I just want to send it back to the calling function. – Ed Tiley Jan 16 '17 at 23:57
  • Yep. Right there in `evt.target.result`, passed to an asynchronous handler function after your main function has returned. The problem (explained in the linked question) has nothing to do with *where* your result is handled, everything to do with *when*. AJAX is not the only place where this arises in JS programming, especially in Cordova, which is aggressively asynchronous. – Paul Roub Jan 17 '17 at 00:02
  • Right! Shown as passed to an asynchronous handler ONLY because it is the only example shown anywhere! I've tried to simply return evt.target.result; I've tried to stuff the string into a global variable The $(".accordine") line is in there ONLY because that's the only example I can find anywhere on the net other than stuffing it into console.log. That line needs to be in the calling function AFTER I've had a chance to mashup the new data with the old data All I want to do is pass a string back to the calling function. Is it really that complex? – Ed Tiley Jan 17 '17 at 01:46
  • It really does require some sort of callback function. Period; it's the way the Cordova/PhoneGap APIs work. A couple of more-narrow questions on the same topic: http://stackoverflow.com/q/18141841/1324, http://stackoverflow.com/q/24064082/1324 – Paul Roub Jan 17 '17 at 19:00
  • OK I think it is penetrating my thick skull. You and David are talking about the onloadend() not the $("accordine")... But then why does the jQuery html(evt.target.result) work without a callback??? – Ed Tiley Jan 17 '17 at 23:56
  • You mean why isn't it `$(".accordine").html(evt.target.result, function() { /* This function will run after the element has been changed */ });`? Because changing the page is fast enough that client-side javascript doesn't need to provide a way of doing it asynchronously. Disk access and network communication take a lot longer. (When you see a page taking a long time to display, it's not because the rendering engine is slow. It's because it takes so long to load the various CSS files, images, scripts, iframes, etc from the network.) – David Knipe Jan 18 '17 at 23:14
  • @David - See that is part of my confusion because by the time that line runs all disk access and network stuff is already done. If you do an alert(evt.target.result); right then and there the result is displayed. You can pop it into a variable and keep working (change values, etc) with it inside the function then write it back to disk whatever. You just can't export the value out without a callback. In thirty years in other languages, I've never seen anything like it. – Ed Tiley Jan 28 '17 at 01:43
  • BTW The best answer to how to create async callbacks was here: http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function -- Lifted a lot of the fog for me. – Ed Tiley Jan 28 '17 at 01:45

1 Answers1

0

"Problem is, I need the content of the file to be returned to the calling function so I can manipulate the data before it is displayed." No you don't. You can manipulate the data without getting it as a return value. Suppose you have a function processData which you want to apply to the data. Then just change the reader.onloadend = part to this:

reader.onloadend = function (evt) {
    $(".accordine").html(processData(evt.target.result));
};
David Knipe
  • 3,417
  • 1
  • 19
  • 19
  • But David, I do need to have the data because I need to push some new data to the top of the file, and possibly remove older data from the bottom, then resave the data so it's available if the device isn't connected. The new data is already in the calling function. – Ed Tiley Jan 16 '17 at 23:43
  • You do have the data, just not as a return value. Whatever it is you want to do with the data, do it inside that anonymous function. That's the only part that runs after the data has been retrieved from disk, and hence the only part where you have access to a variable containing the result of the disk read. – David Knipe Jan 17 '17 at 20:56