Martin Cooper
Martin Cooper

Reputation: 13

Cordova resolveLocalFileSystemURL doesn't return a file object on Windows

I am developing a hybrid app using Cordova, targeting Windows and Android. I am loading a file from disk using resolveLocalFileSystemURL. On Windows, the file created doesn’t actually seem to be a file, according to the console:

[object Object]{end: 380943, lastModified: date, lastModifiedDate: date, localURL: "cdvfile://l...", name: "photo.png", size: 380943, start: 0, type: ".png"}

Compare this with the same file open via an input control like this:

<input type="file" id="files" name="file"/>

[object File]{lastModifiedDate: date, name: "photo.png", size: 380943, type: "image/png", webkitRelativePath: ""}

On Android the console reports both as type "file", so it seems to be something to do with the Windows implementation.

The problem I have is when I try to upload the file from disk to Azure blob storage it fails on Windows. It works on windows if I use the file directly from the input control. It works with both kind of file object on Android. I assume the failure is because the file read from disk isn’t quite a real file – hence the console reports [object Object] rather than [object File]. How can I read the file from disk in Windows, such that it really is a file and so uploads successfully?

This is a test function that demonstrates the difference between the file object when the same file is read from disk or read using an input control. Using Windows, the console output is different for each file. Using Android, it is the same.

<input type="file" id="files" name="file"/>

function loadFile() {
window.resolveLocalFileSystemURL(deviceStorageDirectory + "photo.png", function (oFile) {
    console.log(oFile);
    oFile.file(function (file1) {
        console.log(file1);

        var files = document.getElementById('files').files;
        var file2 = files[0];
        console.log(file2);
    });
});}

Below is the full code. saveFile() allows the user to choose a file and saves it in a temporary area for later upload. uploadBlobByStream reads and uploads the saved file.

uploadBlobByStream(2) uses the file from the input control and works. uploadBlobByStream(1) uses the temp file read from disk and fails on windows.

The command that causes the error is blobService.createBlockBlobFromBrowserFile and the error is "Error in Success callbackId: File1586700476 : a: Invalid HTML File object. cordova.js (312,13)"

<input type="file" id="files" name="file"/>
function saveFile() {
var files = document.getElementById('files').files;
var file = files[0];

var myReader = new FileReader();
myReader.onloadend = function (evt) {
    var file2 = dataURItoBlob(evt.target.result);
    writeLocalFile(deviceStorageDirectory, "photo.png", file2);
};
myReader.readAsDataURL(file);}

function uploadBlobByStream(fileChoice) {
    window.resolveLocalFileSystemURL(deviceStorageDirectory + "photo.png", function (oFile) {
    oFile.file(function (file1) {
        console.log( file1);

        var files = document.getElementById('files').files;
        var file2 = files[0];
        console.log(file2);

        if (fileChoice === 1) {
            fileToUse = file1;
        }
        else { fileToUse = file2; }
        //the two lines below didn't help:
        fileToUse.type = "image/png";
        fileToUse.webkitRelativePath= "";

        var blobService = getBlobService();
        if (!blobService)
            return;

        var blockSize = fileToUse.size > 1024 * 1024 * 32 ? 1024 * 1024 * 4 : 1024 * 512;
         var options = {
             storeBlobContentMD5: false,
             blockSize: blockSize
         };
         blobService.singleBlobPutThresholdInBytes = blockSize;

         blobService.createBlockBlobFromBrowserFile(container, fileToUse.name, fileToUse, options, function (error, result, response) {
             if (error) {
                 console.log(error);
             } else {
                 console.log("success");
             }
         });
    });
});}



function getBlobService() {
blobUri = 'https://' + account + '.blob.core.windows.net';
var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, sas).withFilter(new AzureStorage.Blob.ExponentialRetryPolicyFilter());
return blobService;
}

Upvotes: 1

Views: 911

Answers (0)

Related Questions