Read files synchronously in Cordova

Asked

Viewed 236 times

0

Is there any way in Apache Cordova to read the contents of a file and save to a variable synchronously?

This is because, in the Cordova File API you must use a callback function when reading a file to get the result, and it turns out to be somewhat inconvenient, splitting the code into callbacks.

So, would you have some way to read a file content and save the result in a variable, without needing a callback?


Apache Cordova example callback method:

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
    fs.root.getFile("arquivo.txt", { create: false, exclusive: false }, function (fileEntry) {
        fileEntry.file(function(file) {
            var reader = new FileReader();

            reader.onloadend = function() {
                console.log("Conteúdo do Arquivo: " + this.result);
            };

            reader.readAsText(file);
        }, onErrorReadFile);
    }, onErrorLoadFile);
}, onErrorLoadFs);

Desired method without callbacks: (example)

var texto = funcaoSincronaDeLerArquivo("arquivo.txt")

// manipulação do conteúdo, somente exemplo
if (texto == "admin") {
    window.location = "admin.html";
} else {
    window.location = "user.html";
}

1 answer

1


Due to the nature of Cordova, a framework that works by mediating the communication of your code with the device in native language, you will hardly have this possibility, because Cordova itself makes an asynchronous call in native language and waits for result to pass to the callback you set.

You can use Promise to make control simpler and code cleaner.

Using callbacks your code goes creating a pyramid and the so-called callback Hell:

asyncFunc1(false, function(ret1){
    asyncFunc2(false, function(ret2){
        asyncFunc3(false, function(ret3){
            console.log(ret3);
        }, genericErrorHandler);
    }, genericErrorHandler);
}, genericErrorHandler);

With Promises you linearize this, making it simpler to read and control:

new Promise(function(resolve, reject){
    asyncFunc1(false, resolve, reject);
}).then (function(ret1) {
    return new Promise(function(resolve,reject){
        asyncFunc2(false, resolve, reject);
    });
}).then (function(ret2){
    return new Promise(function(resolve,reject){
        asyncFunc3(false, resolve, reject);
    });
}).then(function(ret3) {
    console.log(ret3);
}, genericErrorHandler);

For example, capture a camera image with callbacks

function getPictureWithoutPromises(successCallback, errorCallback) {
    navigator.camera.getPicture(function (imagePath) {
        window.resolveLocalFileSystemURL(imagePath, function (imageFileEntry) {
            window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (appDataDirEntry) {
                imageFileEntry.copyTo(appDataDirEntry, null, function (newImageFileEntry) {
                    successCallback(newImageFileEntry);
                }, errorCallback);
            }, errorCallback);
        }, errorCallback);
    }, errorCallback);
}

getPictureWithoutPromises(function (imageFileEntry) {
    image.src = imageFileEntry.toURL();
}, function (err) {
    console.log("Error : ", err);
});

And capture the camera image using Promise

function getPictureWithPromises() {
    var sourceImageFileEntry;

    return new Promise(function (returnResolve, returnReject) {
        new Promise(function (resolve, reject) {
            navigator.camera.getPicture(resolve, reject);
        }).then(function (imagePath) {
            return new Promise(function (resolve, reject) {
                window.resolveLocalFileSystemURL(imagePath, resolve, reject);
            });
        }).then(function (imageFileEntry) {
            sourceImageFileEntry = imageFileEntry;
            return new Promise(function (resolve, reject) {
                window.resolveLocalFileSystemURL(cordova.file.dataDirectory, resolve, reject);
            });
        }).then(function (appDataDirEntry) {
            return new Promise(function (resolve, reject) {
                sourceImageFileEntry.copyTo(appDataDirEntry, null, resolve, reject);
            });
        }).then(function (newImageFileEntry) {
                returnResolve(newImageFileEntry)
        });
    });
}

getPictureWithPromises().then(function (imageFileEntry) {
    image.src = imageFileEntry.toURL();
}, function (err) {
    console.log("Error : ", err);
});

You can use the library Cordova-Promise-Fs to use Cordova’s file system functions with promises or study them to implement in your code if it does not meet your needs. But unfortunately there is no way to do this procedure without an asynchronous approach.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.