For several days now I try to upload videofiles via multer to cloudinary. The upload of images works absolutely well, but when I upload a video I face the error:
Cannot read property 'path' of undefined
I logged my FormData the whole way from the frontend via redux-slice and redux-service. Everywhere the field "src" is a file. I logged the headers of the http-request. And they where there. Finally I logged now req.body and must determine, that node has the data.
{ [0] src: 'Pexels Videos 2098989.mp4', [0] ressort: 'Freizeit', [0] theme: 'Lorem Iosum', [0] title: 'Lorem ipsum dolor sit amet, consectetur adipisicing' [0] } [0] (node:4260) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'path' of undefined
What do I have to do to get multer to give me the path of src? I tried now something like const {req.body.src} = req.file, but that not works.
I have now responded to robertklep's response and taken out all my debugging code. Maybe it's more readable now. But it doesn't change the situation. req.file.path is still undefined.
My backend (current state):
const uploadVideo = upload.single("src");
router.post("/", uploadVideo, verifyTokenAndAuthorization, async (req,res)=>{
try{
const result = await cloudinary.uploader.upload(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");
}
});
My multer:
const multer = require("multer");
const path = require("path");
const maxSize = 5 * 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(req.file);
},
})
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;
I add the whole way. My frontend(input):
<FormGroup>
<CrudLabel htmlFor="src">Video hochladen</CrudLabel>
<CrudInput type="file" name="src" id="src"
style={{background:"var(--blue)", color:"var(--white)"}}
ref={fileInput} onChange={fileChange}/>
</FormGroup>
My FormData:
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));
}
My video-slice:
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);
}
})
My http-request:
const API_URL = "http://localhost:5000/api/videos/";
//create
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;
}