I’ve been following a tutorial from YouTube and encountered an error when trying to test my API with Thunder Client. Despite my debugging efforts, I haven’t been able to resolve it. I’d appreciate some help!
I’m getting the following error when testing my API:TypeError: Cannot read properties of undefined (reading 'path')
cloudinaryConfig.js:
<code>import { v2 as cloudinary } from 'cloudinary';
const connectCloudinary = async () => {
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_SECRET_KEY,
export default connectCloudinary;
<code>import { v2 as cloudinary } from 'cloudinary';
const connectCloudinary = async () => {
cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_SECRET_KEY,
});
};
export default connectCloudinary;
</code>
import { v2 as cloudinary } from 'cloudinary';
const connectCloudinary = async () => {
cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_SECRET_KEY,
});
};
export default connectCloudinary;
multer.js:
<code>import multer from 'multer';
const storage = multer.diskStorage({
destination: function (req, file, callback) {
// Specify the directory for storing uploaded files
callback(null, path.resolve('./uploads'));
filename: function (req, file, callback) {
console.log("The file name is: ", file);
// Use the original file name or customize it
callback(null, new Date().toISOString() + file.originalname);
const upload = multer({ storage });
<code>import multer from 'multer';
import path from 'path';
const storage = multer.diskStorage({
destination: function (req, file, callback) {
// Specify the directory for storing uploaded files
callback(null, path.resolve('./uploads'));
},
filename: function (req, file, callback) {
console.log("The file name is: ", file);
// Use the original file name or customize it
callback(null, new Date().toISOString() + file.originalname);
},
});
const upload = multer({ storage });
export default upload;
</code>
import multer from 'multer';
import path from 'path';
const storage = multer.diskStorage({
destination: function (req, file, callback) {
// Specify the directory for storing uploaded files
callback(null, path.resolve('./uploads'));
},
filename: function (req, file, callback) {
console.log("The file name is: ", file);
// Use the original file name or customize it
callback(null, new Date().toISOString() + file.originalname);
},
});
const upload = multer({ storage });
export default upload;
adminRoute.js:
<code>import express from 'express';
import { addDoctor } from '../controllers/adminController.js';
import upload from '../middlewares/multer.js';
const adminRouter = express.Router();
adminRouter.post('/add-doctor', upload.single('image'), addDoctor);
export default adminRouter;
<code>import express from 'express';
import { addDoctor } from '../controllers/adminController.js';
import upload from '../middlewares/multer.js';
const adminRouter = express.Router();
adminRouter.post('/add-doctor', upload.single('image'), addDoctor);
export default adminRouter;
</code>
import express from 'express';
import { addDoctor } from '../controllers/adminController.js';
import upload from '../middlewares/multer.js';
const adminRouter = express.Router();
adminRouter.post('/add-doctor', upload.single('image'), addDoctor);
export default adminRouter;
adminController.js:
<code>import validator from 'validator';
import bcrypt from 'bcrypt';
import { v2 as cloudinary } from 'cloudinary';
import doctorModel from '../models/doctorModel.js';
const addDoctor = async (req, res) => {
const { name, email, password, speciality, degree, experience, about, fees, address } = req.body;
const imageFile = req.file;
if (!name || !email || !password || !speciality || !degree || !experience || !about || !fees || !address) {
return res.json({ success: false, message: 'Missing some details' });
if (!validator.isEmail(email)) {
return res.json({ success: false, message: 'Please enter a valid Email' });
if (password.length < 8) {
return res.json({ success: false, message: 'Please, provide a strong password' });
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const imageUpload = await cloudinary.uploader.upload(imageFile.path, { resource_type: 'image' });
const imageUrl = imageUpload.secure_url;
password: hashedPassword,
address: JSON.parse(address),
const newDoctor = new doctorModel(doctorData);
res.json({ success: true, message: 'Doctor added' });
res.json({ success: false, message: error.message });
<code>import validator from 'validator';
import bcrypt from 'bcrypt';
import { v2 as cloudinary } from 'cloudinary';
import doctorModel from '../models/doctorModel.js';
import path from 'path';
const addDoctor = async (req, res) => {
try {
const { name, email, password, speciality, degree, experience, about, fees, address } = req.body;
const imageFile = req.file;
if (!name || !email || !password || !speciality || !degree || !experience || !about || !fees || !address) {
return res.json({ success: false, message: 'Missing some details' });
}
if (!validator.isEmail(email)) {
return res.json({ success: false, message: 'Please enter a valid Email' });
}
if (password.length < 8) {
return res.json({ success: false, message: 'Please, provide a strong password' });
}
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const imageUpload = await cloudinary.uploader.upload(imageFile.path, { resource_type: 'image' });
const imageUrl = imageUpload.secure_url;
const doctorData = {
name,
email,
image: imageUrl,
password: hashedPassword,
speciality,
degree,
experience,
about,
fees,
address: JSON.parse(address),
date: Date.now(),
};
const newDoctor = new doctorModel(doctorData);
await newDoctor.save();
res.json({ success: true, message: 'Doctor added' });
} catch (error) {
console.log(error);
res.json({ success: false, message: error.message });
}
};
export { addDoctor };
</code>
import validator from 'validator';
import bcrypt from 'bcrypt';
import { v2 as cloudinary } from 'cloudinary';
import doctorModel from '../models/doctorModel.js';
import path from 'path';
const addDoctor = async (req, res) => {
try {
const { name, email, password, speciality, degree, experience, about, fees, address } = req.body;
const imageFile = req.file;
if (!name || !email || !password || !speciality || !degree || !experience || !about || !fees || !address) {
return res.json({ success: false, message: 'Missing some details' });
}
if (!validator.isEmail(email)) {
return res.json({ success: false, message: 'Please enter a valid Email' });
}
if (password.length < 8) {
return res.json({ success: false, message: 'Please, provide a strong password' });
}
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const imageUpload = await cloudinary.uploader.upload(imageFile.path, { resource_type: 'image' });
const imageUrl = imageUpload.secure_url;
const doctorData = {
name,
email,
image: imageUrl,
password: hashedPassword,
speciality,
degree,
experience,
about,
fees,
address: JSON.parse(address),
date: Date.now(),
};
const newDoctor = new doctorModel(doctorData);
await newDoctor.save();
res.json({ success: true, message: 'Doctor added' });
} catch (error) {
console.log(error);
res.json({ success: false, message: error.message });
}
};
export { addDoctor };
When I send a POST request with a file (key: image) and form data, the doctor should be added successfully, and the image should be uploaded to Cloudinary.
I’m using Thunder Client to test the API.
The file upload key is named image.
What could be causing the path to be undefined in req.file?