I want to use the useForm along with a validation system to save data using the append() function and send it to MongoDB with a fetch request. However, when I inspect the formData object, it appears empty, and I receive a ‘no files uploaded’ error when I POST with fetch.
ManageRestaurantForm.jsx
<code>import React from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import DetailsSection from './DetailsSection'
import CuisinesSection from './CuisinesSection'
import MenuSection from './MenuSection'
import ImageSection from './ImageSection'
import { forumFill } from '../../fetch/Fetch'
const ManageRestaurantForm = () => {
const formMethods = useForm();
const { handleSubmit } = formMethods;
const onSubmit = handleSubmit(async (formDataJson) => {
const formData = new FormData();
formData.append("restaurantName", formDataJson.restaurantName);
formData.append("city", formDataJson.city);
formData.append("country", formDataJson.country);
(formDataJson.deliveryPrice * 100).toString());
formDataJson.estimatedDeliveryTime.toString());
formData.append("cuisines", formDataJson.cuisines)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
console.log(formDataJson.menuItems)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
if (formDataJson.imageFiles && formDataJson.imageFiles.length > 0) {
Array.from(formDataJson.imageFiles).forEach((file, index) => {
formData.append(`imageFiles[${index}]`, file);
await forumFill("http://localhost:7000/api/my/restaurant", formData);
<FormProvider {...formMethods}>
<form onSubmit={onSubmit}>
<span className='flex justify-end'>
<button type="submit" className='bg-red-600 text-white h-full mb-10 w-40 rounded hover:rounded-md hover:duration-300 duration-300 p-2 font-bold hover:bg-red-500 cursor-pointer text-2xl'>
export default ManageRestaurantForm
<code>import React from 'react'
import { FormProvider, useForm } from 'react-hook-form'
// PAGES
import DetailsSection from './DetailsSection'
import CuisinesSection from './CuisinesSection'
import MenuSection from './MenuSection'
import ImageSection from './ImageSection'
import { forumFill } from '../../fetch/Fetch'
const ManageRestaurantForm = () => {
const formMethods = useForm();
const { handleSubmit } = formMethods;
const onSubmit = handleSubmit(async (formDataJson) => {
try {
const formData = new FormData();
formData.append("restaurantName", formDataJson.restaurantName);
formData.append("city", formDataJson.city);
formData.append("country", formDataJson.country);
formData.append(
"deliveryPrice",
(formDataJson.deliveryPrice * 100).toString());
formData.append(
"estimatedDeliveryTime",
formDataJson.estimatedDeliveryTime.toString());
formData.append("cuisines", formDataJson.cuisines)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
formData.append(
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
);
});
console.log(formDataJson.menuItems)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
formData.append(
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
);
});
if (formDataJson.imageFiles && formDataJson.imageFiles.length > 0) {
Array.from(formDataJson.imageFiles).forEach((file, index) => {
formData.append(`imageFiles[${index}]`, file);
});
}
console.log(formData)
await forumFill("http://localhost:7000/api/my/restaurant", formData);
} catch (err) {
console.log(err)
}
})
return (
<div>
<FormProvider {...formMethods}>
<form onSubmit={onSubmit}>
{/* FORM COMPONENTS */}
<DetailsSection />
<CuisinesSection/>
<MenuSection />
<ImageSection />
<span className='flex justify-end'>
<button type="submit" className='bg-red-600 text-white h-full mb-10 w-40 rounded hover:rounded-md hover:duration-300 duration-300 p-2 font-bold hover:bg-red-500 cursor-pointer text-2xl'>
Save
</button>
</span>
</form>
</FormProvider>
</div>
)
}
export default ManageRestaurantForm
</code>
import React from 'react'
import { FormProvider, useForm } from 'react-hook-form'
// PAGES
import DetailsSection from './DetailsSection'
import CuisinesSection from './CuisinesSection'
import MenuSection from './MenuSection'
import ImageSection from './ImageSection'
import { forumFill } from '../../fetch/Fetch'
const ManageRestaurantForm = () => {
const formMethods = useForm();
const { handleSubmit } = formMethods;
const onSubmit = handleSubmit(async (formDataJson) => {
try {
const formData = new FormData();
formData.append("restaurantName", formDataJson.restaurantName);
formData.append("city", formDataJson.city);
formData.append("country", formDataJson.country);
formData.append(
"deliveryPrice",
(formDataJson.deliveryPrice * 100).toString());
formData.append(
"estimatedDeliveryTime",
formDataJson.estimatedDeliveryTime.toString());
formData.append("cuisines", formDataJson.cuisines)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
formData.append(
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
);
});
console.log(formDataJson.menuItems)
formDataJson.menuItems.forEach((menuItem, index) => {
formData.append(`menuItems[${index}][name]`, menuItem.name);
formData.append(
`menuItems[${index}][price]`,
(menuItem.price * 100).toString()
);
});
if (formDataJson.imageFiles && formDataJson.imageFiles.length > 0) {
Array.from(formDataJson.imageFiles).forEach((file, index) => {
formData.append(`imageFiles[${index}]`, file);
});
}
console.log(formData)
await forumFill("http://localhost:7000/api/my/restaurant", formData);
} catch (err) {
console.log(err)
}
})
return (
<div>
<FormProvider {...formMethods}>
<form onSubmit={onSubmit}>
{/* FORM COMPONENTS */}
<DetailsSection />
<CuisinesSection/>
<MenuSection />
<ImageSection />
<span className='flex justify-end'>
<button type="submit" className='bg-red-600 text-white h-full mb-10 w-40 rounded hover:rounded-md hover:duration-300 duration-300 p-2 font-bold hover:bg-red-500 cursor-pointer text-2xl'>
Save
</button>
</span>
</form>
</FormProvider>
</div>
)
}
export default ManageRestaurantForm
Above, the formFill function is come from:
<code>// forms/manage-restaurant
export const forumFill = async (url, data) => {
const formDataJSON = JSON.stringify(data);
const rawResponse = await fetch(url, {
'Content-Type': 'application/json'
const content = await rawResponse.json();
console.log(formDataJSON)
<code>// forms/manage-restaurant
export const forumFill = async (url, data) => {
try {
const formDataJSON = JSON.stringify(data);
const rawResponse = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: formDataJSON
});
const content = await rawResponse.json();
console.log(formDataJSON)
console.log(content);
} catch (error) {
console.log(error)
}
};
</code>
// forms/manage-restaurant
export const forumFill = async (url, data) => {
try {
const formDataJSON = JSON.stringify(data);
const rawResponse = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: formDataJSON
});
const content = await rawResponse.json();
console.log(formDataJSON)
console.log(content);
} catch (error) {
console.log(error)
}
};
Backend of this jsx file:
<code>const cloudinary = require("cloudinary").v2;
const mongoose = require("mongoose");
const { Restaurant } = require("../mongodb/models/restaurant");
async createMyRestaurant(req, res) {
if (!req.file || req.file.length === 0) {
return res.status(400).json({ message: "No files uploaded" });
const existingRestaurant = await Restaurant.findOne({ user: req.userId });
if (existingRestaurant) {
return res.status(409).json({ message: "User restaurant already exists" });
const imageFile = req.File;
console.log(`Your imageFile is ${imageFile}`)
const b64 = Buffer.from(imageFile.buffer).toString("base64");
const dataURI = "data:" + imageFile.mimetype + ";base64," + b64;
const uploadResponse = await cloudinary.uploader.upload(dataURI);
const imageUrl = uploadResponse.url;
console.log(`Your imageUrl is ${imageUrl}`)
const restaurant = new Restaurant({
res.status(201).send(restaurant);
res.status(500).json({ message: "Something went wrong :(" });
module.exports = Controller;
<code>const cloudinary = require("cloudinary").v2;
const mongoose = require("mongoose");
const { Restaurant } = require("../mongodb/models/restaurant");
class Controller {
async createMyRestaurant(req, res) {
try {
if (!req.file || req.file.length === 0) {
return res.status(400).json({ message: "No files uploaded" });
}
const existingRestaurant = await Restaurant.findOne({ user: req.userId });
if (existingRestaurant) {
return res.status(409).json({ message: "User restaurant already exists" });
}
const imageFile = req.File;
console.log(`Your imageFile is ${imageFile}`)
const b64 = Buffer.from(imageFile.buffer).toString("base64");
const dataURI = "data:" + imageFile.mimetype + ";base64," + b64;
const uploadResponse = await cloudinary.uploader.upload(dataURI);
const imageUrl = uploadResponse.url;
console.log(`Your imageUrl is ${imageUrl}`)
const restaurant = new Restaurant({
body: req.body,
lastUpdate: new Date(),
});
await restaurant.save();
res.status(201).send(restaurant);
} catch (err) {
console.log(err);
res.status(500).json({ message: "Something went wrong :(" });
}
}
}
module.exports = Controller;
</code>
const cloudinary = require("cloudinary").v2;
const mongoose = require("mongoose");
const { Restaurant } = require("../mongodb/models/restaurant");
class Controller {
async createMyRestaurant(req, res) {
try {
if (!req.file || req.file.length === 0) {
return res.status(400).json({ message: "No files uploaded" });
}
const existingRestaurant = await Restaurant.findOne({ user: req.userId });
if (existingRestaurant) {
return res.status(409).json({ message: "User restaurant already exists" });
}
const imageFile = req.File;
console.log(`Your imageFile is ${imageFile}`)
const b64 = Buffer.from(imageFile.buffer).toString("base64");
const dataURI = "data:" + imageFile.mimetype + ";base64," + b64;
const uploadResponse = await cloudinary.uploader.upload(dataURI);
const imageUrl = uploadResponse.url;
console.log(`Your imageUrl is ${imageUrl}`)
const restaurant = new Restaurant({
body: req.body,
lastUpdate: new Date(),
});
await restaurant.save();
res.status(201).send(restaurant);
} catch (err) {
console.log(err);
res.status(500).json({ message: "Something went wrong :(" });
}
}
}
module.exports = Controller;
Project: githubLink
The expected result was, with the help of useForm creating an object appropriately and POST it into my mongoDB tablet but the error that I face is that formData was empty and unable to send anything.