Ryan Prentiss
Ryan Prentiss

Reputation: 1642

Vue 3 Typescript Composition API: Property 'files' does not exist on type 'EventTarget'

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

Answers (2)

Ryan Prentiss
Ryan Prentiss

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

pytness
pytness

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

Related Questions