multer icon indicating copy to clipboard operation
multer copied to clipboard

I am also having the same error here, the error is saying "Cannot read properties of undefined (reading 'path')

Open smolkawaii1 opened this issue 1 year ago • 1 comments

          I am also having the same error here, the error is saying "Cannot read properties of undefined (reading 'path')

There was an error creating project (status code: 500", but in my case the when I click and submit a new project the file is being uploaded and saved into the "uploads" folder, however it would throw that error. I have also tested it using postman and it works with no errors, I think the problem is in the frontend part but I am not really sure. I hope there is a fix to this. I am using windows by the way.

Here is the my Front end(Form.tsx):

import {
  Box,
  Typography,
  FormControl,
  FormHelperText,
  TextField,
  TextareaAutosize,
  Stack,
  Select,
  MenuItem,
} from "@mui/material";
import { FormProps } from "interfaces/common";
import CustomButton from "./customButton";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import {
  DateRangePicker,
  LocalizationProvider,
  DateRange,
} from "@mui/x-date-pickers-pro";
import axios from "axios";
const Form = ({
  type,
  register,
  handleSubmit,
  formLoading,
  onFinishHandler,
  onFinish,
}: FormProps) => {
  const [value, setValue] = useState<DateRange<Date>>([null, null]);
  const [outputDuration, setOutputDuration] = useState<DateRange<Date>>([
    null,
    null,
  ]);
  const [selectedFile, setSelectedFile] = useState<File | undefined>(undefined);
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      setSelectedFile(e.target.files[0]);
    }
  };
  const onFinishWrapper = async (data: any) => {
    const projectData = {
      ...data,
      file: selectedFile, // Add the selectedFile as the 'file' property
      duration: {
        startDate: value[0],
        endDate: value[1],
      },
      expectOutputDuration: {
        startDate: outputDuration[0],
        endDate: outputDuration[1],
      },
    };

    if (selectedFile) {
      // Upload the file
      const formData = new FormData();
      formData.append("file", selectedFile);
      formData.append("title", data.title);
      formData.append("description", data.description);
      formData.append("fund", data.fund);
      formData.append("source", data.source);
      formData.append("sectorType", data.sectorType);
      formData.append("proponent", data.proponent);
      formData.append("status", data.status);
      formData.append("objective", data.objective);
      formData.append("activity", data.activity);
      formData.append("expectOutput", data.expectOutput);
      formData.append("college", data.college);
      formData.append("intext", data.intext);

      try {
        await axios.post("http://localhost:8080/api/v1/projects", formData);
      } catch (error) {
        console.error("Error uploading file:", error);
      }
    }

    await onFinish(projectData);
  };

  return (
    <Box>
      <Typography fontSize={25} fontWeight={700} color="#11142d">
        {type} a Project
      </Typography>

      <Box
        mt={2.5}
        borderRadius="15px"
        padding="20px"
        sx={{ backgroundColor: "#f6f6f6" }}
      >
        <form
          style={{
            width: "100%",
            display: "flex",
            flexDirection: "column",
            gap: "20px",
          }}
          onSubmit={handleSubmit(onFinishWrapper)}
        >
          <FormControl>
            <FormHelperText
              sx={{
                fontWeight: 500,
                margin: "10px 0",
                fontSize: 16,
                color: "#11142d",
              }}
            >
              Enter Project Title *
            </FormHelperText>
            <TextField
              fullWidth
              required
              id="outlined-basic"
              color="info"
              variant="outlined"
              {...register("title", { required: true })}
            />
          </FormControl>
          {/* Other form fields */}
          <FormControl>
            <FormHelperText
              sx={{
                fontWeight: 500,
                margin: "10px 0",
                fontSize: 16,
                color: "#11142d",
              }}
            >
              Upload File *
            </FormHelperText>
            <input
              type="file"
              accept=".pdf,.doc,.docx,.xls,.xlsx"
              name="file" // Specify the accepted file formats
              onChange={handleFileChange}
            />
          </FormControl>
          <CustomButton
            type="submit"
            title={formLoading ? "Submitting..." : "Submit"}
            backgroundColor="#48C4D3"
            color="#fcfcfc"
          />
        </form>
      </Box>
    </Box>
  );
};

export default Form;

Then here is my upload.js for the multer middleware:

import path from "path";

// Set storage engine
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path.resolve, "./uploads");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + path.extname(file.originalname));
  },
});

// Initialize upload
const upload = multer({
  storage: storage,
  limits: {
    fileSize: 1024 * 1024 * 10, // 10MB file size limit
  },
});

export default upload;

Additionally here is my project.controller.js for creating a new project:

import dotenv from "dotenv";
import path from "path";
dotenv.config();
const createProject = async (req, res) => {
  try {
    // Destructure the required fields from the request body
    const {
      title,
      description,
      sectorType,
      fund,
      source,
      duration,
      proponent,
      status,
      objective,
      activity,
      expectOutput,
      expectOutputDuration,
      college,
      intext,
    } = req.body;

    const file = req.file.path; // Retrieve the file from req.files

    // Create a new Project instance
    const project = await Project.create({
      title,
      description,
      sectorType,
      fund,
      source,
      duration,
      proponent,
      status,
      objective,
      activity,
      expectOutput,
      expectOutputDuration,
      college,
      file,
      intext,
    });

    // Save the project to the database
    await project.save();

    res.status(200).json({ message: "Project/Research added successfully" });
  } catch (error) {
    res.status(500).json({ message: error.message });
    console.log(req.file);
  }
};
export{createProject}

Then hear is the project.routes.js for the routing:

import {
  createProject,
 
} from "../controllers/project.controller.js";
import upload from "../middleware/upload.js";

const router = express.Router();


router.route("/").post(upload.single("file"), createProject);


export default router;

Originally posted by @smolkawaii1 in https://github.com/expressjs/multer/issues/559#issuecomment-1586481551

smolkawaii1 avatar Jun 12 '23 03:06 smolkawaii1

Have you tried upgrading to the version 2 release candidate? npm install [email protected]

joeyguerra avatar Apr 01 '24 22:04 joeyguerra