- Joined
- Sep 12, 2022
- Messages
- 39
- Reaction score
- 0
The form is to send fetched data(from another API) alongside an added note. The fetched data is well received, I logged it to the console. The form appears to send the fetched data and note correctly to the backend, I logged req.body to the console. The issue I'm facing is that the response I get is 400. I tested via Postman manually sending the data and note to the form POST API and it works, it saves correctly to the database. It does not work via the app.
Frontend
JavaScript:
// backend/controllers/hire.js
const Vehicle = require("../models/Hire");
const { StatusCodes } = require("http-status-codes");
const { BadRequestError, NotFoundError } = require("../errors");
const cloudinary = require("../cloudinary/cloudinary");
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads"); // Set the destination folder for uploaded files
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname); // Set the filename for uploaded files
},
});
const fileFilter = function (req, file, cb) {
// Check file type
if (!file.originalname.match(/\.(jpg|jpeg|png|svg)$/i)) {
return cb(new Error("Only image files are allowed!"), false);
}
cb(null, true);
};
const upload = multer({ storage: storage, fileFilter: fileFilter });
const AddHire = async (req, res) => {
console.log("backend", req.body);
upload.array("pictures", 5)(req, res, async (error) => {
if (error) {
// Handle multer upload error
if (error.message === "Unexpected field") {
return res
.status(StatusCodes.BAD_REQUEST)
.json({ error: "Maximum of 5 images allowed" });
}
return res.status(StatusCodes.BAD_REQUEST).json({ error: error.message });
}
if (!req.files || req.files.length === 0) {
// No files uploaded
return res
.status(StatusCodes.BAD_REQUEST)
.json({ error: "No files uploaded" });
}
if (req.files.length > 5) {
// More than 5 files uploaded
return res
.status(StatusCodes.BAD_REQUEST)
.json({ error: "Maximum of 5 images allowed" });
}
const pictureUrls = [];
// Upload each picture to Cloudinary and store the secure URLs
for (const file of req.files) {
const uniqueIdentifier =
Date.now() + "-" + Math.round(Math.random() * 1e9);
const publicId = `${req.user.userId}_vehicle_${uniqueIdentifier}`;
const result = await cloudinary.uploader.upload(file.path, {
public_id: publicId,
width: 500,
height: 500,
crop: "fill",
});
pictureUrls.push(result.secure_url);
}
req.body.pictures = pictureUrls;
req.body.createdBy = req.user.userId;
// Extract the note from the request body
const { note, ...vehicleDetails } = req.body;
// Create a new vehicle entry with the user's note
const vehicleWithNote = { ...vehicleDetails, note };
// Store the new vehicle entry in the database
const vehicle = await Vehicle.create(vehicleWithNote);
res.status(StatusCodes.CREATED).json({ vehicle });
});
};
module.exports = {
AddHire,
};
Frontend
JavaScript:
"use client";
import { useState } from "react";
import sendFormWithVehicleDetails from "@/lib/postHire";
export default function Form({ vehicle }: { vehicle: Vehicle }) {
const {
name,
seat,
price,
description,
type,
pictures,
colour,
transmission,
} = vehicle;
const [note, setNote] = useState("");
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const vehicleDetails: FormDetails = {
name: name,
pictures: pictures,
description: description,
colour: colour,
transmission: transmission,
type: type,
seat: seat,
price: price,
};
// Create an object with 'note' and 'vehicleDetails'
const dataToSend = {
note: note,
...vehicleDetails,
};
try {
await sendFormWithVehicleDetails(dataToSend);
console.log("Form submitted");
} catch (error) {
console.error(error);
}
}
return (
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label htmlFor="examplenote1" className="form-label">
Add note
</label>
<input
type="text"
className="form-control"
id="exampleInputEmail1"
aria-describedby="textHelp"
placeholder="Bring umbrellas"
value={note}
onChange={(e) => {
setNote(e.target.value);
}}
/>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
);
}
JavaScript:
type FormDetails = {
name: string;
pictures: string[];
description: string;
colour: string;
transmission: string;
type: string;
seat: number;
price: number;
};
JavaScript:
import Cookies from "js-cookie";
export default async function sendFormWithVehicleDetails(
vehicleDetails: FormDetails
) {
const url = "http://127.0.0.1:3000/api/v1/hire";
const token = Cookies.get("token");
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
authorization: `Bearer ${token}`,
},
body: JSON.stringify(vehicleDetails),
});
if (!response.ok) {
const errorResponse = await response.json();
throw new Error(
`Request failed with status ${response.status}, ${errorResponse}`
);
}
const data = await response.json();
return data;
}