Capacitor File Picker doesn't return a blob on native mobile

467 views Asked by At

I use @capawesome/capacitor-file-picker for pick files on mobile. Yet it does not return blob.

const result = await FilePicker.pickFiles({
      types: ['application/pdf'],
        multiple: false,
      });

const file = result.files[0];

if(file.blob){ **//fails here because file.blob not exist**
        const rawFile = new File([file.blob as BlobPart], file.name, {
          type: file.mimeType,
        });
        callback(rawFile, file.name)
      } 

when I console.log the file:

mimeType: "application/pdf"
modifiedAt: 1696191033806
name: "filename.pdf"
path: "file:///path/to/file/filename.pdf"
size: 1332512

There's no blob :(

Get the blob of the file, when console.log(file) it should be:

blob: `sum-blob`
mimeType: "application/pdf"
modifiedAt: 1696191033806
name: "filename.pdf"
path: "file:///path/to/file/filename.pdf"
size: 1332512
1

There are 1 answers

0
Ivan Yunus On

So actually capacitor file picker, when pick file we can use the readData option to be true. So it would look like this:

const result = await FilePicker.pickFiles({
  types: ['application/pdf'],
  multiple: false,
  readData: true,
});

It will return:

data:"JVBERi0xLjcKJb/3ov4KMSAwIG9iago8PCAvVHlwZSAvT2JqU3RtIC9MZW5ndGggMzEyOCAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTiA4MCAvRmlyc3QgNjI3ID4+CnN0cmVhbQp4nNVa…"
mimeType: "application/pdf"
modifiedAt: 1696191033806
name: "filename.pdf"
path: "file:///path/to/file/filename.pdf"
size: 1332512

That data is a base64 of the file, so we can convert it to blob using this function I found around the internet:

dataURItoBlob(dataURI: any) {
    const byteString = window.atob(dataURI);
    const arrayBuffer = new ArrayBuffer(byteString.length);
    const int8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < byteString.length; i++) {
      int8Array[i] = byteString.charCodeAt(i);
    }
    const blob = new Blob([int8Array], { type: 'image/png' });    
    return blob;
}

So then we can:

const fileBlob = this.dataURItoBlob(base64);
const rawFile = new File([fileBlob as BlobPart], file.name, {
    type: file.mimeType,
});

It return the base64 as blob :) that rawFile already contain the blob!