Upload video with multer and cloudinary - can't read req.file

In my Mern-Stack I have build a fileuploader using multer and cloudinary. The upload of images works really fine, but when I try to upload a video, the console tells me:

Cannot read property path of undefined

I console.log my Formdata on the whole way. In my dashboard, my redux-slice, my redux-service. Everywhere the value “src” is a file. So it must be multer that not works. Can someone help me out? Thanks
Multer storage:

const multer = require("multer");
const path = require("path");
const maxSize = 1 * 1024 *1024;
 const storage = multer.diskStorage({
        destination:(req,file, callback)=>{
            callback(null,  path.resolve(process.cwd(), 'frontside/public/uploads'));
        },
        fileName: (req, file, callback)=>{
            callback(null, Date.now()+ "--"+ path.extname(file.originalname));
            console.log(file.originalname)
        },
    })

const upload = multer({
    storage:storage,
    fileFilter:(req,file,callback)=>{
        if(
            file.mimetype == "image/png"||
            file.mimetype == "image/jpg" ||
            file.mimetype == "image/jpeg" ||
            file.mimetype == "video/mp3" ||
            file.mimetype == "video/mp4"
        ){
            callback(null, true);
        } else{
            callback(null,false)
            return callback(new Error("Only .png, .jpg, .jpeg, .mp3, .m4 allowed"))
        }
    },
    limits:{fileSize: maxSize}
});

module.exports = upload

backend:

const upload = require("../utils/multer");
const cloudinary = require("../utils/cloudinary");
const path = require("path");
//create
const uploadVideo = upload.single("src");
router.post("/",verifyTokenAndAuthorization, async (req,res)=>{
    uploadVideo(req,res, function(err){
        if(err){
            console.log(err);
            return;
        } else{
            console.log('req.file:', JSON.stringify(req.file));
            
            next();
        }
    })
    try{
        const result = cloudinary.uploader.upload_large(req.file.path, {
            upload_preset: "Mern_redux-practice",
            resource_type: "video",
        }
        );
        const newVideos= new Videos({
            cloudinary_id: result.public_id,
            ressort: req.body.ressort,
            theme: req.body.theme,
            title:req.body.title,
            src: result.secure_url,
        })
        const savedVideos= await newVideos.save();
        res.status(200).json(savedVideos);
    } catch(error){
        res.status(403)
        console.log(error)
        throw new Error("Action failed");
    }
});
1 Like

Is the file size limit not a bit small for videos? Not really sure how multer handles the limit or where or how it throws when it exceeds it. What happens if you upload an image that is larger than the limit?

Hello lasjorg, thanks for your answer. Images are absolute no problem. I have no images that are larger than the limit. I raised the limit now on 5mb. I even taken it completly out. But whatever I do, multer not recognizes req.file. This error is thrown very often, but I found no useful solutions in the net. Deleting the header “Content-Type” brings nothing. I have async and await in every function, so it cannot be possible that it is a time problem, I think. But I cannot declare what can be the differense between img and video.

I cleared the cache now and multer logs the right file, so it must be a cloudinary problem. I put the question in their forum and wait for answer.

Not sure how cloudinary would affect the request object in the code you posted.

I have the problem that sometimes Multer shows the correct video data despite the error and sometimes not. So I could imagine that it is a time problem. Though I have only used asynchronous functions, on the way to backend.

Hello lasjorg, I am really thankfull, that you want to help me, I put the whole code:

const onSubmit = (e)=>{
    e.preventDefault();
   const videosData = new FormData();
   videosData.append("ressort", formdata.ressort);
   videosData.append("theme", formdata.theme);
   videosData.append("title", formdata.title);
   videosData.append("src", filedata);
   for(let value of videosData){
    console.log(value);
   }
    dispatch(createVideos(videosData));
  }
export const createVideos = createAsyncThunk("videos/create", async (videosData, thunkAPI)=>{
    if(videosData){
        for(let value of videosData){
            console.log(value)
        }
    }
    try{
        const token = thunkAPI.getState().auth.user.accessToken;
        return await videosService.createVideos(videosData, token);
    } catch(error){
        const message = (error.response 
            && error.response.data 
            && error.response.data.message) 
            || error.message 
            || error.toString();
        return thunkAPI.rejectWithValue(message);
    }
})
const createVideos = async (videosData, token)=>{
    if(videosData){
        for(let value of videosData){
            console.log(value);
        }
    }
    const config = {
        headers:{
        'Content-Type': 'application/json',
        token: `Bearer ${token}` 
        }
    }
    const response = await axios.post(API_URL, videosData, config);
    console.log(response.data);
    return response.data;
}

I doubt I can help you with this just by looking at static code. You have a lot of moving parts, the front-end, back-end, third-party packages, and third-party SaaS (Cloudinary). Who knows where the issue is, I definitely don’t just by looking at the code. I mean it might be an async issue, but it might also not.

You will have to debug each part of the chain and figure out when it is breaking. But that may not even tell you why it is breaking.

Not sure how cloudinary would affect the request object in the code you posted video
Instagram.