11

I'm using the checkFile function from File API plugin in Ionic 3 to check if a file exists locally. The Promise rejects with the following error :

FileError {code: 5, message: "ENCODING_ERR"}

From what I see on the Mozilla Docs of the File API, the problem is that "The URL is malformed." However, I don't see how is the URL malformed. Here is the relevant code showing how I'm calling the function plus the actual values of involved variables (The value of baseDirectory is set to file:///data/user/0/ch.protectator.fehpedia/files/) :

let baseDirectory = this.file.dataDirectory;
let fileToCheck = "File:Icon Portrait Abel.png";

let promise = this.file.checkFile(this.file.dataDirectory, fileName).then(bool => {
    // Things
}, reason => {
    console.error(reason);
});

And that's the Promise that fails. What's strange about that case is that I actually tried to display that image later in the code, ignoring if it has been found by File.checkFile, and the image displays.

In the HTML template, I later use :

<img [src]="imgUrl">

where imgUrl is set using :

this.imgUrl = this.file.dataDirectory + '/' + "File:Icon Portrait Abel.png";

So the image exists and displays correctly when called by the WebView, but the Native File plugin tells me the URL is malformed, even to me it seems to be exactly the same URL. That's where I'm stuck, I don't know what to change for the code to work. Should checkFile be used in a different way ? Also, a more precise cause of failure would help, but all I got is ENCODING_ERR, I don't know what actual part of the URL seems malformed.

Kewin Dousse
  • 3,880
  • 2
  • 25
  • 46
  • From where you get this value `this.file.dataDirectory`? Can you show the code for that too? – Sampath Aug 28 '17 at 00:43
  • `this.file` is injected in the constructor of the class, and it's the `File` class from the Ionic Native API. Thus, `dataDirectory` is https://ionicframework.com/docs/native/file/#dataDirectory – Kewin Dousse Aug 28 '17 at 00:47

6 Answers6

20

After looking through similar cases, I've found no solution nor documentation about this specific case. But while experimenting with different values, I found what caused this error : :. Yes, the colon. The one present in the file name.

While I still have no explanation about why : causes the native File plugin to fail but not the web view, removing : from the file name effectively allows File to see it without raising an ENCODING_ERR. While this is not an optimal solution, this workaround is effective.

Kewin Dousse
  • 3,880
  • 2
  • 25
  • 46
  • 2
    "While I still have no explanation about why : causes the native File plugin to fail" Colon (:) is a resverved character that can not be used in filenames in Windows systems (but can be used in Linux systems). Maybe for compatibility, File plugin reserved all characters on both Windows and Linux systems. (List of characters forbidden in filenames )[https://stackoverflow.com/a/31976060/4511424] – Ramon-san Aug 30 '17 at 10:24
  • I was having the same issue. This didn't fix my issue, but for those experiencing it: I removed all my platform `ionic cordova platform rm ios`, deleted the `plugins` directory and re-added the ios platform and it worked again – Timmy O'Mahony May 01 '19 at 17:39
  • 1
    How can we handle if we are using base64 concept e.g. data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,UEsD................ ? – Code_S Mar 01 '21 at 16:19
2

In my case, I let "File:///" in the route and now it is working.

1

None of the answers solve my problem. It was very simple, I was using the wrong Directory to save a file in iOS. I was using "Cache" but kept getting the error

I change to

this.file.tempDirectory;

And worked!

Ari Waisberg
  • 1,186
  • 1
  • 12
  • 23
0

Just cross check with creating simple file name first.

In my case the file name I was using was not a proper file name.

Code that was giving the same error

    const fileName = localStorage.getItem(appGlobals.UserData.email) + '_' + new Date() + '.mp3';
this.file.createFile(this.file.dataDirectory, fileName, true)
.then((fileEntry: FileEntry) => {
  //do something with the file
}).catch(err => {
  alert(JSON.stringify(err));
});

code after changes

    const fileName = localStorage.getItem(appGlobals.UserData.email) + '_' + new Date().getTime() + '.mp3';
this.file.createFile(this.file.dataDirectory, fileName, true)
.then((fileEntry: FileEntry) => {
// do something with the file
}).catch(err => {
  alert(JSON.stringify(err));
});
Abhishek
  • 528
  • 6
  • 17
0

In my case this worked for me

resolveLocalFileSystemURL(`${cordova.file.externalDataDirectory.replace(/^file:\/\//g, '')}record252202022149.3gp`, function(entry) { 
    console.log(entry);
}, (e) => console.error(e))
Uzbekjon
  • 11,655
  • 3
  • 37
  • 54
Leonardo Pineda
  • 990
  • 8
  • 10
0

Make sure that you are pointing to the correct directory to save the files to depending on the platform. I created this utility to get the correct directory for Android and iOS:

    getDeviceDirectoryToSaveFile(): string {
     if (this.platform.is('android')) {
      return this.file.externalDataDirectory;
     } else if (this.platform.is('ios')) {
      return this.file.applicationStorageDirectory+"/Documents";
     }
    }
zulkarnain shah
  • 971
  • 9
  • 20