Reputation: 1642
Using Vue 3's Composition API, I want to temporarily display the local selected photo as the button's background image. Upon uploading, the style.backgroundImage
will return to its default.
The first set of errors I was running into was the Object is possibly 'null'
on photo.value
& e.target
. I resolved these with a conditional. Let me know if this is not Vue 3 best practice.
The current error I am facing is the Property 'files' does not exist on type 'EventTarget'.
on e.target.files[0]
. Is this a type declaration issue? How would this be best resolved?
The online solution (<HTMLInputElement>e.target).files[0]
does not seem to work for Vue. Returns Object is possibly 'null'.
<template>
<button ref="photo" @click="uploadPhoto"></button>
<input type="file" ref="photoInput" @change="showTempPhoto" style="display: none" />
</template>
setup(){
const photo = ref<HTMLDivElement | null>(null)
const photoInput = ref<HTMLInputElement | null>(null)
const uploadPhoto = () => {
photoInput.value?.click()
}
const showTempPhoto = (e: Event) => {
if (photo.value && e.target){
const url = URL.createObjectURL(e.target.files[0])
photo.value.style.backgroundImage = url
photo.value.onload = () => URL.revokeObjectURL(url)
}
}
}
Upvotes: 1
Views: 1194
Reputation: 1642
Deconstructing the url declaration helped me to resolved the issue.
const target = <HTMLInputElement>e.target
Followed by a null
check,
const url = URL.createObjectURL(target.files && target.files[0])
then finally a clean-up of the backgroundImage
assignment
photo.value.style.backgroundImage = `url('${url}')`
Upvotes: 0
Reputation: 387
The class Event
may or may not have a target as shown here:
let my_event = new Event('event_type');
console.log(my_event.target)
// outputs null
And typescript does not know either the element type of the target or if it is not null; so you would have to check explicitly if target
is not null
and cast e.target
to HTMLInputElement
:
const showTempPhoto = (e: Event) => {
if (photo.value && e.target !== null){
const url = URL.createObjectURL((<HTMLInputElement>e.target).files[0])
photo.value.style.backgroundImage = url
photo.value.onload = () => URL.revokeObjectURL(url)
}
}
Upvotes: 2