Issue with passing fetched data to POST form. How can I?

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.


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;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,286
Latest member
ChristieSo

Latest Threads

Top