The FileReader API is event driven. You define custom behavior in its event handlers when it either succeeds or fails to read a file and then pass a File object to one of the methods, such as
readAsText The result of the method, if successful, can finally be retrieved in the
The FileReader methods work asynchronously but don't return a Promise. And attempting to retrieve the result immediately after calling a method will not work, as the
.onload event handler, which fires only after the FileReader has successfully finished reading the file and sets the FileReader's
.result property, has not fired yet. This can make FileReader a bit of a pain to work with when integrating it with an application.
Wrapping it With a Promise
A solution to make FileReader more pleasant to work with is to wrap its result in a Promise. Here's an example:
This function returns a Promise of a string that will resolve or reject only after the firing of the
.onerror event handlers, respectively. If the Promise is rejected the FileReader will abort and, in this case, return a custom DOMException but you can
reject with whatever you like. One good alternative is the FileReader's
.error property, which will also be a DOMException.
A Simplified API with Async/Await
Wrapping the result of a FileReader in a Promise allows us to simply
await the result of our
readUploadedFileAsText function and expect a string. Here's an example
onchange handler we could pass to a
<input type="file /> element (Full example on CodePen)
The CodePen link above shows the above code doing manual DOM manipulation. For an example in a React application using React's event system, look here.