The Problem:
I want to post form data (uncluding strings, numbers, arrays) AND a file to backend using one useFetch()
call, in TypeScript.
Specifically, I want to use a library like useFetch
to make a request that includes both form data (such as strings, numbers, and arrays) and a file, in a single request. However, I am having trouble finding a way to do this that is compatible with TypeScript and the FormData
class.
I have tried adding numbers and arrays to the FormData
instance, but I get errors from TypeScript because FormData.append()
only accepts strings or Blob
s. I have also tried JSONifying numbers and arrays and posting them as strings, but then I get errors on the backend.
I have also tried posting form data as a simple JS Object, but this does not work for files.
Ultimately, I want to be able to post all of the data in a single request, without having to make multiple requests or convert the data on the backend.
The Solutions:
Solution 1: Use `FormData` Efficiently
To post both form data and files using a single `useFetch` call, follow these steps:
-
Create a
FormData
instance. -
Append the file to the
FormData
instance usingformData.append("file", yourfileorimage)
. -
Append additional form data to the
FormData
instance using the following loop:
const formdata = {
title: book.title,
authors: authorIds,
publisher: book.publisher?.id,
year: book.year,
pages: book.pages,
description: book.description,
contents: book.contents,
};
for (const item in formdata) {
formData.append(item, formdata[item]);
}
- Call
useFetch
with the following parameters:
YOUR-API-URL
as the URLPUT
as the HTTP methodformData
as the body{ "cache-control": "no-cache" }
as the headers
The cache-control
header ensures that the browser does not cache the response.
This method allows you to post both form data and files using a single fetch call.
Solution 2: Use `FormData` with JSON Stringification
In this solution, we create a single FormData
instance and append the form data and file to it. For arrays and numbers, we JSON stringify them before appending them to the FormData
. This ensures that the data is sent correctly and can be parsed by the backend.
<!– begin snippet: js hide: false console: true babel: false –>
<!– language: lang-js –>
<template>
<div>
<div>
<input
type="file"
@change="fileChange"
/>
</div>
<button @click.prevent="sendDataAndUploadFile">Send Data and Upload file</button>
</div>
</template>
<script lang="ts" setup>
const uploadedFile = ref<File | null>(null)
function fileChange(file: Event): void {
const fileData = file.target as HTMLInputElement
if (fileData.files) {
uploadedFile.value = fileData.files[0]
}
}
const BookData = {
title: 'The Adam',
author: 'John Doe',
publisher: 'John Doe',
ratings: [4, 5, 4.5]
}
async function sendDataAndUploadFile() {
const formData = new FormData()
if (uploadedFile.value) {
formData.append('cover_image', uploadedFile.value)
for (const [key, value] of Object.entries(BookData)) {
if (Array.isArray(value)) {
for (const rating of value) {
formData.append(`${key}[]`, rating.toString())
}
} else {
formData.append(key, value as string)
}
}
}
await useFetch('/api/upload', {
method: 'POST',
body: formData
})
}
</script>
<template>
<div>
<div>
<input
type="file"
@change="fileChange"
/>
</div>
<button @click.prevent="sendDataAndUploadFile">Send Data and Upload file</button>
</div>
</template>
<style scoped lang="css"></style>
<!– end snippet –>
Q&A
How to pass FormData and File in a single useFetch call?
You must need to pass FormData()
into useFetch and append your file/image and another data in FormData()
Is it possible to post form data (strings, numbers, arrays) and a file in one useFetch call, using TypeScript?
Yes, it is possible to post form data and a file in one useFetch call using TypeScript by utilizing the FormData() object.
Video Explanation:
The following video, titled "Nuxt 3 full course build and deploy | #Nuxtjs #vue #nuxt3 - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
... Fetch Data ⏳ (02:13:58) Auth State ⏳ (02:23:20) 3 Kinds of Middleware ⏳ (02:35:13) Server Routes ⏳ (02:43:32) Deploy to Netlify Social ...
The following video, titled "Nuxt 3 full course build and deploy | #Nuxtjs #vue #nuxt3 - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
... Fetch Data ⏳ (02:13:58) Auth State ⏳ (02:23:20) 3 Kinds of Middleware ⏳ (02:35:13) Server Routes ⏳ (02:43:32) Deploy to Netlify Social ...