Rename a File with JavaScript in the Browser

A super concise tutorial on using JavaScript to rename files in the browser. We’ll quickly cover how to update a file object and read its contents. Let’s get started!

Updating the File Object

Let’s create a new file using the File constructor, we’ll then rename this file in a couple seconds.

const myFile = new File(['hello-world'], 'my-file.txt');

Time to rename our file…

myFile.name = 'my-file-final-1-really.txt';

console.log(newFile);
// Browser logs: File {name: "my-file.txt", …}

Nope, didn’t work. Turns out we can’t update the name property of a file.

To rename a file we have to create a new file and pass our new name to the File constructor.

const myRenamedFile = new File([myFile], 'my-file-final-1-really.txt');

console.log(myRenamedFile);
// Browser logs: File {name: "my-file-final-1-really.txt", …}

To check if the file contents is the same we can read our file using the FileReader API.

const myReader = new FileReader();
myReader.readAsText(myRenamedFile);
myReader.onload = () => console.log(myReader.result);
// Browser logs: "hello-world"

Great, it has the same contents. ☀️

Surprise, this doesn’t work on Internet Explorer 11. ⛈

We can work around the age of IE11 by creating a Blob instead of a file object. Let’s create a tiny helper function that safely does this for us.

const createFile = (bits, name) => {
    try {
        // If this call fails, we go for Blob
        return new File(bits, name);
    }
    catch (e) {
        // If we reach this point a new File could not be constructed
        var myBlob = new Blob(bits);
        myBlob.lastModified = new Date();
        myBlob.name = name;
        return myBlob;
    }
}

Now we can safely create files like this:

const mySafeFile = createFile(['hello-world'], 'my-file.txt');

console.log(mySafeFile);
// Modern browser logs: File {name: "my-file.txt", …}
// Internet Explorer logs: Blob {name: "my-file.txt", …}

Yay! 🎉

Note that the File constructor also takes a third “options” argument, this can contain the type of the file and the lastModified date of the file.

Let’s update our createFile function so it also supports the “options” argument.

const createFile = (bits, name, options) => {
    try {
        // If this fails, we go for Blob
        return new File(bits, name, options);
    }
    catch (e) {
        // If we're here a new File could not be constructed
        var myBlob = new Blob(bits, options || {});
        myBlob.lastModified = new Date();
        myBlob.name = name;
        return myBlob;
    }
}

Now we can create an actual plain/text file.

const myTextFile = createFile(['hello-world'], 'my-file.txt', 
    { type: 'plain/text' }
);

A small caveat. Our files can now be of type Blob or File. When using the instanceof operator to test for types it’s best to test for Blob.

The following will be true on modern browsers but false on browsers that don’t support the File constructor (like Internet Explorer 11).

const testFile = createFile(['hello-world'], 'my-test.txt');
console.log(testFile instanceof File);
// Modern browser logs: true
// Internet Explorer logs: false

Testing for Blob instead of File will return the correct result on all browsers as File is a subclass of Blob.

const testFile = createFile(['hello-world'], 'my-test.txt');
console.log(testFile instanceof Blob);
// Modern browser logs: true
// Internet Explorer logs: true

That’s it!

Conclusion

We learned that updating a file object is not possible but that we can easily copy the contents of a file to a new file and give our new file a name.

To verify that the contents of the file was actually copied we took a quick look using the FileReader API.

Finally to help with cross browser compatibility we created a tiny function that can create a “File” object on all relevant browsers, “relevant” being relative.

Rik Schennink

Web enthusiast

to pqina.nl