#I want to send Array of Object has with FormData
1 messages · Page 1 of 1 (latest)
Based on the information provided in the extracts, it seems you are trying to append an array of objects to a FormData instance. However, FormData.append() method only accepts a USVString or Blob (which includes subclasses such as File). If you pass an object to this method, it will be converted to a string using the toString() method, which is likely not what you want.
Unfortunately, the extracts do not provide a direct solution to your problem. However, you might consider stringifying your array of objects before appending it to the FormData instance, and then parse it back into an object on the server side.
Here's an example of how you might do this:
async function onSubmit(values: CreateTourValues) {
const formData = new FormData();
Object.entries(values).forEach(([key, value]) => {
if (Array.isArray(value)) {
// Stringify array of objects
formData.append(key, JSON.stringify(value));
} else if (value) {
formData.append(key, value);
}
});
}
On the server side, you would then parse the string back into an array of objects:
export async function POST(request: Request) {
const formData = await request.formData();
const galleryTour = JSON.parse(formData.get('galleryTour'));
// Now galleryTour is an array of objects
}
Please note that this is a general JavaScript/TypeScript solution and might need adjustments based on your server-side setup. The extracts do not provide specific information about handling such cases in Next.js. For more detailed guidance, you might want to refer to the Next.js documentation (https://nextjs.org/docs) or seek advice on a platform like StackOverflow.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@turbid flower kapa.ai is still learning and improving, please let us know how it did by reacting below
@uncut jolt Thanks its good, but the issue is array of object has File, and it return empty object because of JSON.stringify()
Let me check the knowledge base for you. One moment! :books:
I see, you're correct. JSON.stringify() does not handle File objects well. In this case, you might need to handle the File objects separately from the other data in your array of objects.
Unfortunately, the provided extracts do not contain a direct solution to this problem. However, a common approach is to append each file to the FormData instance separately, using a unique key for each one. Here's an example:
async function onSubmit(values: CreateTourValues) {
const formData = new FormData();
Object.entries(values).forEach(([key, value]) => {
if (key === 'galleryTour' && Array.isArray(value)) {
value.forEach((item, index) => {
if (item.imageGallery) {
// Append each file with a unique key
formData.append(`galleryTour[${index}].imageGallery`, item.imageGallery);
}
if (item.titleGallery) {
// Append other data normally
formData.append(`galleryTour[${index}].titleGallery`, item.titleGallery);
}
});
} else if (value instanceof File) {
formData.append(key, value);
} else if (value) {
formData.append(key, value.toString());
}
});
}
On the server side, you would then handle these files separately from the other data.
Please note that this is a general JavaScript/TypeScript solution and might need adjustments based on your server-side setup. The extracts do not provide specific information about handling such cases in Next.js. For more detailed guidance, you might want to refer to the Next.js documentation (https://nextjs.org/docs) or seek advice on a platform like StackOverflow.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@turbid flower kapa.ai is still learning and improving, please let us know how it did by reacting below
@uncut jolt Thanks, but i want to return data like that
values: { body: string; title: string; checkIn: Date; checkOut: Date; guests: string; pricePerNight: string; galleryTour: { titleGallery?: string | undefined; imageGallery?: File | undefined; }[]; feauturedImage?: File | undefined; }
Let me check the knowledge base for you. One moment! :books:
I understand that you want to maintain the structure of your data when sending it to the server. However, due to the limitations of FormData and how it handles complex objects and files, you might need to adjust your approach.
Unfortunately, the provided extracts do not contain a direct solution to this problem. However, a common approach is to append each file and each field of the objects in your array separately to the FormData instance, using a unique key for each one. Here's an example:
async function onSubmit(values: CreateTourValues) {{
const formData = new FormData();
Object.entries(values).forEach(([key, value]) => {{
if (key === 'galleryTour' && Array.isArray(value)) {{
value.forEach((item, index) => {{
if (item.imageGallery) {{
// Append each file with a unique key
formData.append(`galleryTour[${{index}}][imageGallery]`, item.imageGallery);
}}
if (item.titleGallery) {{
// Append other data normally
formData.append(`galleryTour[${{index}}][titleGallery]`, item.titleGallery);
}}
}});
}} else if (value instanceof File) {{
formData.append(key, value);
}} else if (value) {{
formData.append(key, value.toString());
}}
}});
}}
On the server side, you would then handle these files and fields separately from the other data.
Please note that this is a general JavaScript/TypeScript solution and might need adjustments based on your server-side setup. The extracts do not provide specific information about handling such cases in Next.js. For more detailed guidance, you might want to refer to the Next.js documentation (https://nextjs.org/docs) or seek advice on a platform like StackOverflow.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@turbid flower kapa.ai is still learning and improving, please let us know how it did by reacting below
@uncut jolt This is my server code , it's action how i can change it to handle files
`export async function createTour(formData: FormData) {
const session = await getServerSession(authOptions);
if (!session) {
redirect("/");
}
const values = Object.entries(formData.entries());
const {
title,
body,
checkIn,
checkOut,
guests,
feauturedImage,
pricePerNight,
galleryTour,
} = createTourFormSchema.parse(values);
const slug = ${toSlug(title)}-${nanoid(10)};
let imageTour: string | undefined = "";
if (feauturedImage) {
const blob = await put(
featured/${slug}${path.extname(feauturedImage.name)},
feauturedImage,
{
access: "public",
addRandomSuffix: false,
}
);
imageTour = blob.url;
}
const tour = await prisma.tour.create({
data: {
title,
slug,
body,
checkIn,
checkOut,
guests: parseInt(guests),
pricePerNight: parseInt(pricePerNight),
feauturedImage: imageTour,
userId: session?.user.id,
},
});
if (galleryTour) {
galleryTour.forEach(async (gallery: any) => {
const blob = await put(
places/${slug}${path.extname(gallery?.imageGallery?.name)},
gallery?.imageGallery,
{
access: "public",
addRandomSuffix: false,
}
);
await prisma.gallery.create({
data: {
title: gallery.titleGallery as string,
image: blob.url,
tourId: tour.id,
},
});
});
}
redirect("/");
}`
Let me check the knowledge base for you. One moment! :books:
Based on the provided extracts, it seems you are trying to handle file uploads on the server side in a Next.js application. However, the extracts do not provide a direct solution to your problem.
In your current server code, you are already handling file uploads with the put function, which presumably uploads the file to a storage service and returns a blob with the file URL. You are then storing this URL in your database.
If you are having trouble with this code, it might be because you are trying to parse the FormData entries directly into your createTourFormSchema. FormData entries are key-value pairs where the value could be a File object, and trying to parse this directly might cause issues.
Instead, you might need to handle the File objects separately from the other data. For example, you could iterate over the FormData entries, check the type of each value, and handle it accordingly:
const values = {};
for (let [key, value] of formData.entries()) {
if (value instanceof File) {
// Handle file upload and store the resulting URL in `values`
const blob = await put(`featured/${slug}${path.extname(value.name)}`, value, {
access: "public",
addRandomSuffix: false,
});
values[key] = blob.url;
} else {
// Store other data directly in `values`
values[key] = value;
}
}
// Now you can parse `values` with your schema
const {
title,
body,
checkIn,
checkOut,
guests,
feauturedImage,
pricePerNight,
galleryTour,
} = createTourFormSchema.parse(values);