Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kendrick's avatar

File input onchange method not triggered

Before uploading an image, I am trying to re-place the current filename of the User with the chosen file from the input through an onchange method.

With the current setup below, the img changes into a blank space and hides the src, without throwing an error.

<img id="img" :src="filename" class="image">
<input type="file" name="file" ref="file" accept="image/*" @change="onChange">

props: ['user'],

data() {
    return { 
        filename: this.user.url
    }
},

methods: {
    onChange(file) {
        this.filename = this.$refs.file.file
    }
},

If I try this.filename = this.$refs.file.files img turns into src="[object FileList]"

Also not working: this.filename = file.src

Any idea what I am missing?

0 likes
18 replies
kendrick's avatar

this.filename = this.$refs.file.files[0].name returns the correct filename of the chosen file. But as it is not on the server yet, it returns the ? img.

this.filename = file.target.result also won't work

How can I just show the chosen file before uploading it?

flightsimmer668's avatar

Hi here @splendidkeen

data() {
    return { 
        filename: this.user.url
    }
},

Uploading the file on the page using the above code does not give you a URL; instead you'll get a File object.

If I'm correct in assuming that your use case is to replace an image or file related to the user and persist that URL in the database, then you need to somehow upload the file to your application server and generate its URL from there. The file upload can be a POST request using a FormData object. For example:

methods: {
    onLoad(file) {
        this.filename = this.$refs.file.files[0]

	let formData = new FormData();
            formData.append('form', this.file)

            axios.post('/your-post-url-for-file-upload', 
                formData,
                {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    },
                }
            ).then(response => {
                console.log('Done uploading file')
            })
    }
},

How can I just show the chosen file before uploading it?

As for that question, this should point you in the right direction https://stackoverflow.com/questions/12368910/html-display-image-after-selecting-filename

kendrick's avatar

@flightsimmer668 - After choosing a file, I want to pre-view the chosen file by re-placing the current :src"filename" with the chosen input. Without uploading. After that, the User pushes the upload button.

Basically, just put the chosen file as the image, then upload and persist it separately. onLoad should be named onChange - sorry for the confusion.

flightsimmer668's avatar

I edited my earlier reply with a link to using FileReader objects to show an image preview

kendrick's avatar

@flightsimmer668 - Already tried this one, within blade. But within vue, it won't work the same way.

onChange(input) {
        var reader = new FileReader();
        reader.onload = function (e) {
           $('#img') // id="img" on the img
           .attr('src', e.target.result) 
        };
        reader.readAsDataURL(input.files[0]);
},

gives me Error in v-on handler: "TypeError: undefined is not an object (evaluating 'input.files[0]')"

flightsimmer668's avatar

In Vue devtools in your browser, what is the value of this.filename after the onChange(file) method runs?

kendrick's avatar

With:

onChange(file) {
this.filename = file.src
}

it turns to filename: undefined

flightsimmer668's avatar

And if you do

onChange(file) {
this.filename = file
}

there is an object?

kendrick's avatar

This returns filename: Event ("[object Event]")

flightsimmer668's avatar

If you make the following changes:

onChange() {
this.filename = this.$refs.file.files[0]
}

does that return a File object instead of an Event?

flightsimmer668's avatar

Good. I think you're getting somewhere now. Try the following changes next:

<img id="img" ref="image" :src="previewFile" class="image">
data() {
    return { 
        filename: this.user.url,
	previewFile: null,
    }
},
onChange() {
	this.previewFile = this.$refs.file.files[0]

  	const reader = new FileReader();

	reader.addEventListener("load", () => {
    	this.$refs.image.src = reader.result;
  }, false);

    	reader.readAsDataURL(this.previewFile);

}

Hopefully something like the above works.

kendrick's avatar

@flightsimmer668 - Thank you, also read the stack with the previewFile logic. This won't work either. With your setup it returns, again a File object. Additionally, I wouldn't show the current user image. Which is needed.

A few days ago, I got it working, it must be something simple. Can't remember what it was.

But basically, I just need to replace the current user image with the chosen file. Then the user sees it, and can push the upload button. Trying different ways for hours now.

flightsimmer668's avatar

Just made an edit that adds a ref to the img tag and a callback within the onChange method

flightsimmer668's avatar
Level 11

If it's working then you already have the basic framework. The below code is more convoluted but I think it should work if you really want to stick with the "filename logic"

<img id="img" ref="image" :src="imgSrc" class="image">
data() {
    return { 
        filename: this.user.url,
	previewFile: null,
	previewUrl: null,
    }
},
onChange() {
	this.previewFile = this.$refs.file.files[0]

  	const reader = new FileReader();

	reader.addEventListener("load", () => {
    	this.previewUrl = reader.result;
  }, false);

    	reader.readAsDataURL(this.previewFile);

}
computed: {
	imgSrc() {
		if (this.previewUrl != null) {
			return this.previewUrl
		} else {
			return this.filename
		}
	}
}
kendrick's avatar

@flightsimmer668 - Thank you.

It also works with:


onChange(file) {

this.filename = this.$refs.file.files[0]

                const reader = new FileReader();

                reader.addEventListener("load", () => {
                    this.$refs.image.src = reader.result;
                }, false);

                reader.readAsDataURL(this.filename);
}

But throws an error Failed to load resource: the server responded with a status of 404 (Not Found) [Object File]

Will also try your new setup - Update: works without the error, based on best answer.

Thank you @flightsimmer668

Please or to participate in this conversation.