Read files synchronously in Cordova

0

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

This is because, in the Cordova File API you should use a callback function when reading a file to get the result , and ends up being somewhat inconvenient, splitting the code into callbacks.

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

Apache Cordova sample 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";
}
    
asked by anonymous 14.01.2017 / 19:07

1 answer

1

Because of 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 that possibility, since Cordova itself makes an asynchronous call in the native language and awaits results to pass for the callback you define.

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

Using callbacks your code will create a pyramid and callback 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, capturing 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 cordova-promise-fs library to use the file system functions of cordova 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.

    
10.03.2017 / 06:03