Properties of files received from an <input type="file">
are read-only.
For example, the following attempt to re-write file.name
would either fail silently or throw TypeError: Cannot assign to read only property 'name' of object '#<File>'
.
<input onchange="onchange" type="file">
onchange = (event) => {
const file = event.target.files[0];
file.name = 'foo';
}
Attempting to create a copy via Object.assign({}, file)
fails (creates an empty object).
So how does one clone a File
object?
My solution lay in the File
constructor:
https://developer.mozilla.org/en-US/docs/Web/API/File#Implementation_notes
Which itself is an extension of Blob
:
https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
let file = event.target.files[0];
if (this.props.distro) {
const name = 'new-name-here' + // Concat with file extension.
file.name.substring(file.name.lastIndexOf('.'));
// Instantiate copy of file, giving it new name.
file = new File([file], name, { type: file.type });
}
Note the first argument to File()
must be an array, not simply the original file.
You can use FormData.prototype.append()
, which also converts a Blob
to a File
object.
let file = event.target.files[0];
let data = new FormData();
data.append("file", file, file.name);
let _file = data.get("file");