DEV Community

Alan Schio
Alan Schio

Posted on • Edited on

9

Vue and Input File - Clear File or Select same file

Have you ever had the case where ou have a file selector component, you clear the file model but then you can't select the same file again?

File selection

Codepen: https://codepen.io/schirrel/pen/YzRGrvq

Well its kinda hard and curious to explain.
First of all to the TL/DR:
You need to use Vue's $refs and set the input to null.

Now if you want to understand why, let's pass thru some important stuff:

First: Vue doesn't work with v-model and file input, even has a discussion about it on the offical Vue's repo: Discussion.

Now lets undestand why doesnt work, two main things:

  1. input with type="file" only triggers change event, while v-model listen to input event.
  2. v-model needs to set the value html attribute, if you ever try to do :value="myFileModel" this error will show up:

Error in nextTick: "InvalidStateError: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

So with this comes a question: how to a clear a file, and most important, how make it possible to select again?

Lets paint a simple use case: You have your own file wrapper the uses a file input (obviously) but you save the file on the data. Example:

<template>
 <label for="inputFile">
      Click here to select you file
      <input type="file" name="inputFile" id="inputFile" @change="selectFile" />
    </label>
    <span v-if="file">
      File Selected {{ file.name }}
      <button @click="clearFile">remove</button>
    </span>
</template>
<script>
export default {
  data() {
    return {
      file: null
    };
  },
  methods: {
    selectFile(event) {
      this.file = event.target.files[0];
    },
    clearFile() {
      this.file = null;
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Even if clearFile is setting file as null, when selecting the file again the @change wont be triggered again. Thats why because the html value attribute still the same, the file prop on data doesn't affect it. Take a look at the codepen example.

Once we have seen that :value don't work with files, the proper way to do this is acessing the HTML <input type="file" /> and reset this value programmatically.

By adding a ref="fileInput" to the <input> and inside the clearFile method add:

this.$refs.fileInput.value = null
Enter fullscreen mode Exit fullscreen mode

Now it works:

Vue select same file

The codepen final solution: https://codepen.io/schirrel/pen/XWyjeOw

Note: this is common behavior across frameworks;

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (1)

Collapse
 
gabrielaschlemper profile image
Gabriela Schlemper

thanks for that!

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay