javascriptwebfilereaderwebfontswoff

FileReader.readAsDataURL() reader result is empty for font files such as .ttf, .woff, and .woff2


I am building a web interface that allows the user to upload a custom font. The problem is that I am unable to convert the font files (specifically, .ttf, .woff, and .woff2 files) to base64 via the FileReader.readAsDataUrl() so that I can then PUT these files via my API.

I can successfully reasAsDataUrl .png and .jpg files, and receive those files' data as a base64 encoded strings, no problem. However, when I try to do the same thing with a .ttf, .woff, or .woff2 file, reader.result is empty although the FileReader doesn't throw any error.

I am using input elements to allow the user to select a font:

<input type="file" accept="application/font-woff" onChange={handleUpload}/>

The handleUpload function looks like this:

handleUpload: () => (event: Object) => {
   const { currentTarget: element } = event;

   if (!element.files) { return; }

   const file = element.files[0];

   const reader = new FileReader();
   reader.onerror = (error) => {
     console.error('Error: ', error);
   };
   reader.readAsDataURL(file);

   console.log(reader.result); // reader.result is empty
}

This is the file object that I am passing to the readAsDataURL function.


Solution

  • I figured it out :-)

    readAsDataURL was working successfully but I was returning reader.result before the read was complete. I changed my code to include

    reader.addEventListener('load', () => {
      change(name, reader.result);
    }, false);
    

    and now it's working!

    Additional info (edit): The reason why it was working for the image files was because in the onUpload function for those input components I was rendering a preview image which depended on the file being done loading... as a side effect of waiting for the file in order to render the preview, I was also ensuring that the file was loaded before I did anything with it afterwards. I was happy to realize this because if one day, for some reason, I removed the image preview piece, my image upload would have also broken!