javascriptcordovaionic-frameworkjszip

Niether FileReader nor Cordova File Read working


I have been struggling with this problem for a couple of days: I cannot manage to read a file's content in Android. I have tried this both ways, and in both I have the same results: it never goes further of the file read (execution freezes there), I don't get a result, I don't get an error.

I have tried it with JS FileReader

        const dirContent: Entry[] = await this.cordovaFile.listDir(this.file.dataDirectory, 'scans');

        for (const entry of dirContent) {
            if (entry.isFile) {
                (entry as FileEntry).file(file => {
                    const reader = new FileReader();

                    reader.onloadend = (data) => console.log('I never get here');
                    reader.readAsText(file);
                    console.log('I get here');
                });
            }
        }

And also tried it with Cordova readAsURL

        const dirContent: Entry[] = await this.file.listDir(this.file.dataDirectory, 'scans');
        for (const entry of dirContent) {
            if (entry.isFile) {
                const e = entry as FileEntry;
                const path = this.file.dataDirectory + 'scans'; // d.fileName.substring(0, index);
                const index = e.nativeURL.lastIndexOf('/');
                const filename = e.nativeURL.substring(index + 1);
                console.log('I  get here');
                const contents = await this.file.readAsDataURL(path, filename);
                console.log('I never get here');
            }
        }

On both the same: execution stops without results or error. I assume that the file is found, as I get errors if I make a mistake in the path or filename (on propose). The file of the only file in the directory I is under 500KB, RAM should not be an issue.

By the way, my goal is to pack the files in a zip file using JSZip, so an alternative to reading the contents is also welcome.


Solution

  • It was exhausting and complicated, but I found the solution here: https://github.com/ionic-team/capacitor/issues/1564#issuecomment-538200971. The whole thread is full of proposed solutions, I recommend a detailed read, as the solution that worked for me might not be useful for you.

    I finally made a new function as follows:

    private async getFileContents(fileEntry: FileEntry): Promise<string> {
        return new Promise<string>(resolve => {
            fileEntry.file(iFile => {
                const fileReader = new FileReader();
                const zoneOriginalInstance = (fileReader as any).__zone_symbol__originalInstance;
                const reader = zoneOriginalInstance || fileReader;
                reader.onloadend = (data) => resolve(data.target._result as string);
                reader.readAsDataURL(iFile);
            });
        });
    }
    

    The key is this __zone_symbol__originalInstance. After ORing this to FileReader the onloadend finally triggers with the proper result.