0

I have created a function to remove a specified directory using the cordova-plugin-file plugin. The function itself works correctly and removes the directory, but I am trying to return a success or failure result based on the outcome and am completely stuck.

(function() {
var app = {
    ...

    function removeDirectory(path) {
        var result = false;

        window.resolveLocalFileSystemURL(path, function(dir, status) {
            dir.removeRecursively(function(dir, status) { // Success callback
                result = true;
                console.log(result); // true
            }, function(error) { // Failure callback
                console.log('Error removing directory: ' + getFileError(error.code));
            });
            console.log(result); // false
        });

        console.log(result); // false
        return result;
    }
}
})();

resolveLocalFileSystemURL() and removeRecursively() both do not return a value.

No matter what I try, result always ends up being false. I've even tried using a global (outside of the IIFE) variable but even that doesn't hold its value correctly.

It seems like a variable scope issue but I just don't know how to fix it.

Prawny
  • 123
  • 1
  • 7
  • 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) – Andreas Jul 18 '16 at 11:09

2 Answers2

0

The A in AJAX stands for asynchronous. That means sending the request (or rather receiving the response) is taken out of the simple excution steps. In this example, .send returns immediately and the next statement, return result;, is executed before the function you passed as success callback was even called.

This means when you're returning, the listener you've defined did not execute yet, which means the value you're returning has not been defined.

function onComplete(a){ // When the code completes, do this
    alert(a);
}

function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);
}

document.body.innerHTML = getFive(onComplete);

// like the above functionality based on change your code.

HariKrishnan.P
  • 1,204
  • 13
  • 23
0

window.resolveLocalFileSystemURL is an asynchronous function. That is, the code will not wait for its return before proceeding further.

So this is basically how your code path is looking when removeDirectory is called.

  1. Instantiate variable result to false.
  2. Call window.resolveLocalFileSystemURL(...) and insert a callback function for the API to invoke upon the processing is finished.
  3. Note: during this stage your code will move on to the next line console.log(result). Since result is still false; as during this time the file deletion is still happening.
  4. Lastly call return without waiting on window.resolveLocalFileSystemURL to return.

To fix this - you should do something like...

See:

(function() {
  var app = {
    function removeDirectory(path, done) {
        var result = false;

        window.resolveLocalFileSystemURL(path, function(dir, status) {
            dir.removeRecursively(function(dir, status) { // Success callback
                result = true;
                console.log(result); // true
                return done(null, result); // Success, return.
            }, function(error) { // Failure callback
                console.log('Error removing directory: ' + getFileError(error.code));
                return done(error, result); // oops failed!
            });
        });
    }
}
})();

Essentially what you are doing here is to make removeDirectory take in a done parameter which would be a callback function. So when dir.removeRecurisvely is done with its job, it could use the callback function to return a response to the original caller for removeDirectory.

Samuel Toh
  • 18,006
  • 3
  • 24
  • 39
  • 1
    The callback is returning the `result` variable. What does this fix? Who receives the return value? – Andreas Jul 18 '16 at 11:37
  • @Andreas - Thanks for pointing this out. I have modified the solution to include a new `done` parameter for the main `removeDirectory` function and the `return` statements has been updated to call `done` the callback function when a response is ready to be sent back. – Samuel Toh Jul 18 '16 at 11:46
  • @Prawny please let us know whether this resolves your issue. Happy to assist. – Samuel Toh Jul 18 '16 at 11:54
  • @SamuelToh Unfortunately not - the `done` callback has the same problems. – Prawny Jul 18 '16 at 13:41
  • @Prawny care to elaborate more on what is happening with the done callback? – Samuel Toh Jul 18 '16 at 13:43
  • I'm trying to assign the `done` result (true|false) to a local variable, defined just before the callback, by both normal assignment and function return value - both unsuccessful. – Prawny Jul 18 '16 at 13:46
  • @Prawny `done` has to be a parameter to function `removeDirectory` and when u call it, u need to pass in a callback function for it. E.g `removeDirectory('blah', function(delResult) { console.log('return from removeDirectory: ' + delResult); });` is that how you are calling removeDirectory now? – Samuel Toh Jul 18 '16 at 19:53
  • Got it to work now. Not sure what I did differently than yesterday apart from defining the function inline... Thank you. – Prawny Jul 19 '16 at 16:11