This shows how to convert a Blob or File object to base64 string.
Conversion from a Blob to a base64 happens when a image is retrieved via an api, while conversion from a File to a base64 is for file uploading via form input.
For both cases, we can use FileReader.readAsDataURL()
function.
Therefore, this time uses a common function for the converting.
Common function with FileReader.readAsDataURL()
This function is used in these 2 two cases:
- Conversion of File object inputed in
<input type="file" />
- Conversion of image (Blob object) retreaved via an api
export const fileToBase64 = (file: File | Blob): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result as string);
};
reader.readAsDataURL(file);
reader.onerror = reject;
});
File to base64
Assume you want to preview multiple images inputed in <input type="file" />
.
You have the following element.
<input type="file" multiple onChange={onSelectFiles} />
const onSelectFiles = async (e: React.ChangeEvent<HTMLInputElement>) => {
const tempFileList: { fileName: string, base64String: string }[] = [];
await Promise.all(
[].map.call(e.target.files, async (file: File) => {
tempFileList.push({
fileName: file.name,
base64String: file.type.indexOf('image') > -1 ? await fileToBase64(file) : '',
});
})
);
// Do something like updating the component state or redux state.
};
A File object is an array like object, but we cannnot use Array prototype functions like map()
. So [].map.call()
is used here.
That function picks only image files for the conversion by using file.type.indexOf('image') > -1
.
If you allow single file for the <input>
, you can just use this.
const onSelectFiles = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files[0];
const tempFileList: { fileName: string, base64String: string } = {
fileName: file.name,
base64String: file.type.indexOf('image') > -1 ? await fileToBase64(file) : '',
};
// Do something like updating the component state or redux state.
};
Blob to base64
When you convert an api-fetched binary image data to base64, you might encounter the following error in the common function above.
TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.
That is due to the responseType
in the api request.
You need to set responseType: 'blob'
like this. (This case uses axios
for example.)
const base64String = await fileToBase64(
(
await axios.get(`${endpointUrl}`, {
headers: {
Accept: 'application/octet-stream',
},
responseType: 'blob',
})
).data as Blob
)
That's it 👍👍👍