multer
multer copied to clipboard
I am also having the same error here, the error is saying "Cannot read properties of undefined (reading 'path')
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
Have you tried upgrading to the version 2 release candidate? npm install [email protected]