What could be reason the file upload feature of component isn't working? #8192
-
I have a component-that's from Laravel Jetstream stub-for updating user profile that used to work (and should work, really) that I can't get to work anymore. Whenever there is a file input, an empty array is sent to the backend, when there's no file, other inputs get sent. This is my component code: <template>
<jet-form-section @submitted="updateProfileInformation">
<template #title> Profile Information </template>
<template #description>
Update your account's profile information and email address.
</template>
<template #form>
<!-- Profile Photo -->
<div
class="col-span-6 sm:col-span-4"
v-if="$page.props.jetstream.managesProfilePhotos"
>
<!-- Profile Photo File Input -->
<input type="file" class="hidden" ref="photo" @change="updatePhotoPreview" />
<jet-label for="photo" value="Photo" />
<!-- Current Profile Photo -->
<div class="mt-2" v-show="!photoPreview">
<img
:src="user.profile_photo_url"
:alt="user.first_name"
class="rounded-full h-20 w-20 object-cover"
/>
</div>
<!-- New Profile Photo Preview -->
<div class="mt-2" v-show="photoPreview">
<span
class="block rounded-full w-20 h-20 bg-cover bg-no-repeat bg-center"
:style="'background-image: url(\'' + photoPreview + '\');'"
>
</span>
</div>
<jet-secondary-button
class="mt-2 mr-2"
type="button"
@click.prevent="selectNewPhoto"
>
Select A New Photo
</jet-secondary-button>
<jet-secondary-button
type="button"
class="mt-2"
@click.prevent="deletePhoto"
v-if="user.profile_photo_path"
>
Remove Photo
</jet-secondary-button>
<jet-input-error :message="form.errors.photo" class="mt-2" />
</div>
<!-- Signature -->
<div class="col-span-6 sm:col-span-4">
<!-- Signature File Input -->
<input
type="file"
class="hidden"
ref="signature"
@change="updateSignaturePreview"
/>
<jet-label for="signature" value="Signature" />
<!-- Current Signature -->
<div class="mt-2" v-show="!signaturePreview">
<img
:src="user.signature_url"
:alt="user.first_name"
class="rounded-full h-20 w-20 object-cover"
/>
</div>
<!-- New Signature Preview -->
<div class="mt-2" v-show="signaturePreview">
<span
class="block rounded-full w-20 h-20 bg-cover bg-no-repeat bg-center"
:style="'background-image: url(\'' + signaturePreview + '\');'"
>
</span>
</div>
<jet-secondary-button
class="mt-2 mr-2"
type="button"
@click.prevent="selectNewSignature"
>
Select A Signature
</jet-secondary-button>
<jet-secondary-button
type="button"
class="mt-2"
@click.prevent="deleteSignature"
v-if="user.signature_path"
>
Remove Signature
</jet-secondary-button>
<jet-input-error :message="form.errors.signature" class="mt-2" />
</div>
<!-- First Name -->
<div class="col-span-6 sm:col-span-4">
<jet-label for="first_name" value="First Name" />
<jet-input
id="first_name"
type="text"
class="mt-1 block w-full"
v-model="form.first_name"
autocomplete="first_name"
/>
<jet-input-error :message="form.errors.first_name" class="mt-2" />
</div>
<!-- Last Name -->
<div class="col-span-6 sm:col-span-4">
<jet-label for="last_name" value="Last Name" />
<jet-input
id="last_name"
type="text"
class="mt-1 block w-full"
v-model="form.last_name"
autocomplete="last_name"
/>
<jet-input-error :message="form.errors.last_name" class="mt-2" />
</div>
<!-- Email -->
<div class="col-span-6 sm:col-span-4">
<jet-label for="email" value="Email" />
<jet-input
id="email"
type="email"
class="mt-1 block w-full"
v-model="form.email"
/>
<jet-input-error :message="form.errors.email" class="mt-2" />
</div>
<!-- Mobile Phone Number -->
<div class="col-span-6 sm:col-span-4">
<jet-label for="mobile_phone_number" value="Mobile Phone Number" />
<jet-input
id="mobile_phone_number"
type="text"
class="mt-1 block w-full"
v-model="form.mobile_phone_number"
autocomplete="mobile_phone_number"
/>
<jet-input-error :message="form.errors.mobile_phone_number" class="mt-2" />
</div>
<!-- Address -->
<div class="col-span-6 sm:col-span-4">
<jet-label for="address" value="Contact Address" />
<jet-input
id="address"
type="text"
class="mt-1 block w-full"
v-model="form.address"
autocomplete="address"
/>
<jet-input-error :message="form.errors.address" class="mt-2" />
</div>
</template>
<template #actions>
<jet-action-message :on="form.recentlySuccessful" class="mr-3">
Updated.
</jet-action-message>
<jet-button :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
Update
</jet-button>
</template>
</jet-form-section>
</template>
<script setup>
import { computed, ref } from "vue"
import JetButton from "@/Jetstream/Button.vue"
import JetFormSection from "@/Jetstream/FormSection.vue"
import JetInput from "@/Jetstream/Input.vue"
import JetInputError from "@/Jetstream/InputError.vue"
import JetLabel from "@/Jetstream/Label.vue"
import JetActionMessage from "@/Jetstream/ActionMessage.vue"
import JetSecondaryButton from "@/Jetstream/SecondaryButton.vue"
import { useForm, usePage } from "@inertiajs/vue3"
const photo = ref(null)
const signature = ref(null)
const photoPreview = ref(null)
const signaturePreview = ref(null)
const user = computed(() => usePage().props.auth.user)
const form = useForm({
first_name: user.value.first_name,
last_name: user.value.last_name,
email: user.value.email,
mobile_phone_number: user.value.mobile_phone_number,
address: user.value.address,
photo: null,
signature: null
})
const selectNewPhoto = () => photo.value.click()
const updatePhotoPreview = () => {
if (! photo.value.files[0]) return
const reader = new FileReader()
reader.onload = (e) => {
photoPreview.value = e.target.result
}
reader.readAsDataURL(photo.value.files[0])
}
const deletePhoto = () =>
form.delete(route("current-user-photo.destroy"), {
preserveScroll: true,
onSuccess: clearPhotoFileInput
})
const clearPhotoFileInput = () => photo?.value && (photo.value = null)
const selectNewSignature = () => signature.value.click()
const updateSignaturePreview = () => {
if (! signature.value.files[0]) return
const reader = new FileReader()
reader.onload = (e) => {
signaturePreview.value = e.target.result
}
reader.readAsDataURL(signature.value.files[0])
}
const deleteSignature = () =>
form.delete(route("current-user-signatute.destroy"), {
preserveScroll: true,
onSuccess: () => clearSignatureFileInput()
})
const clearSignatureFileInput = () => signature?.value && (signature.value = null)
const updateProfileInformation = () => {
photo.value ? ((form.photo = photo.value.files[0]), console.log(form.photo)) : null
signature.value ? (form.signature = signature.value.files[0]) : null
form.put(route("user-profile-information.update"), {
preserveScroll: true,
errorBag: "updateProfileInformation",
onSuccess: () => (clearPhotoFileInput(), clearSignatureFileInput())
})
}
</script> What is wrong with this code? How can I resolve this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
In your above code it's not a minimum reproduction. Can you provide a minimum reproduction or a repository? Thanks. |
Beta Was this translation helpful? Give feedback.
-
I found out what the issue was and it's not a vue problem. It has to do with the Inertia form method I was using and the correct usage of http methods. It turns out I shouldn't use a const form = useForm({
_method: "PUT",
first_name: user.value.first_name,
last_name: user.value.last_name,
email: user.value.email,
mobile_phone_number: user.value.mobile_phone_number,
address: user.value.address,
photo: null,
signature: null
})
const updateProfileInformation = () => {
photo.value ? (form.photo = photo.value.files[0]) : null
signature.value ? (form.signature = signature.value.files[0]) : null
form.post(route("user-profile-information.update"), {
preserveScroll: true,
errorBag: "updateProfileInformation",
onSuccess: () => (clearPhotoFileInput(), clearSignatureFileInput())
})
} |
Beta Was this translation helpful? Give feedback.
I found out what the issue was and it's not a vue problem. It has to do with the Inertia form method I was using and the correct usage of http methods. It turns out I shouldn't use a
put
method for file uploads. Changing this portion of my code resolved the issue: