I am trying to update a user profile by making a PUT request to an endpoint that accepts both text and file. Using axios, when I set the "Content-type": "multipart/form-data" text fields are not updated and image in also not uploaded but setting this "Content-type": "application/json", updates all text fields but throws validation error for image.
My script code looks like this
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import http from "../http-common";
const router = useRouter();
const file = ref(null);
const form = ref({
first_name: profile.userProfile.first_name,
last_name: profile.userProfile.last_name,
});
function handleImage() {
form.value.photo = file.value.files[0];
}
const updateProfile = async () => {
try {
const res = await http.put("user/profile", form.value, {
headers: {
Accept: "application/json",
"Content-type": "multipart/form-data",
},
});
if (form.value.photo) {
console.log("image upload pending");
}
if (res.data.success) {
alert(res.data.message);
}
router.push("/profile");
} catch (error) {
console.log(error);
}
};
</script>
This is the form
<form
class="space-y-8 divide-y divide-hrgray"
enctype="form.data"
@submit.prevent="submit"
>
<div
class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-center sm:border-t sm:border-hrgray sm:pt-5"
>
<label
for="photo"
class="block text-sm font-medium text-gray-700"
>
Photo
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="flex items-center">
<input
ref="file"
v-on:change="handleImage"
type="file"
/>
</div>
</div>
</div>
</div>
<div class="pt-8 space-y-6 sm:pt-10 sm:space-y-5">
<div
class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-hrgray sm:pt-5"
>
<label
for="first-name"
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
>
First name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<input
type="text"
v-model="form.first_name"
name="first-name"
id="first-name"
autocomplete="given-name"
class="max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md"
/>
</div>
</div>
<div
class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-hrgray sm:pt-5"
>
<label
for="last-name"
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
>
Last name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<input
type="text"
v-model="form.last_name"
name="last-name"
id="last-name"
autocomplete="family-name"
class="max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md"
/>
</div>
</div>
</div>
<div class="pt-5 pb-10">
<div class="flex justify-end">
<button
type="submit"
@click="updateProfile()"
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-book hover:bg-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Save
</button>
</div>
</div>
</form>
What is the right way to pass the image and text in the API PUT request?