Reputation: 147
It is the first time I am trying to upload a file to cloudinary. After fixing several errors, I have the issue, that the upload is not working and the console.log() in uploadResult tells me that:
Cannot read property 'public_id' of undefined
Here is my code from the backend:
router.post("/", verifyTokenAndAuthorization, async (req,res)=>{
const {img,ressort, theme, title, content} = req.body;
try{
const uploadResult = await cloudinary.uploader.upload(img,{
folder: MainNews
}, (error, img)=>{
if(error){
console.log(error)
}
console.log("* Same image, uploaded with a custom public_id");
console.log("*" + img.public_id);
console.log("* " + img.url);
waitForAllUploads("MainNews", error, img);
});
const newMainNews = new MainNews({
ressort,
theme,
title,
content,
img: {
public_id: uploadResult.public_id,
url: uploadResult.secure_url
}
});
const savedMainNews = await newMainNews.save();
res.status(200).json(savedMainNews);
} catch(error){
res.status(403)
throw new Error("Action failed");
}
});
The createAsyncThunk from my redux-slice:
export const createMainNews = createAsyncThunk("mainNews/create", async (mainnewsData, thunkAPI)=>{
try{
const token = thunkAPI.getState().auth.user.accessToken;
return await mainnewsService.createMainNews(mainnewsData, token);
} catch(error){
const message = (error.response &&
error.response.data &&
error.response.data.message)
|| error.message
|| error.toString()
return thunkAPI.rejectWithValue(message);
}
})
The redux-service:
const API_URL = "http://localhost:5000/api/mainNews/";
const createMainNews = async (mainnewsData, token)=>{
const config = {
headers: {
'Content-Type': `multipart/form-data`,
token: `Bearer ${token}`,
},
}
const response = await axios.post(API_URL, mainnewsData, config);
return response.data;
}
Here is my frontend:
const [formdata, setFormdata] = useState(
{
ressort:"",
theme:"",
title:"",
content:"",
}
)
const {ressort,theme,title,content} = formdata;
const [fileData, setFileData] = useState({
img:""
})
const {img} = fileData;
const fileInput = useRef(img);
const fileChange = (e)=>{
console.log(fileInput.current.files);
setFileData(fileInput.current.files[0])
}
console.log(fileData); //works and it is a file
const handleChange = (e)=>{
setFormdata((prevState)=>({
...prevState,
[e.target.name]: e.target.value
}))
}
const onSubmit = (e)=>{
e.preventDefault();
const data = new FormData();
data.append("img", fileData);
data.append("ressort", formdata.ressort);
data.append("theme", formdata.theme);
data.append("title", formdata.title);
data.append("content", formdata.content)
const mainnewsData ={
data,
}
dispatch(createMainNews(mainnewsData));
}
Upvotes: 1
Views: 142
Reputation: 137
Try this
router.post("/", verifyTokenAndAuthorization, async (req,res)=>{
const {img, ressort, theme, title, content} = req.body;
try{
const uploadResult = await cloudinary.uploader.upload(img,{
folder: MainNews
});
const newMainNews = new MainNews({
ressort,
theme,
title,
content,
img: {
public_id: uploadResult.public_id,
url: uploadResult.secure_url
}
});
const savedMainNews = await newMainNews.save();
res.status(200).json(savedMainNews);
} catch(error){
res.status(403).send(false);
}
});
you don't have to use return keyword because response will automatically sended to client without return.
I can't 100% sure if this work.
Upvotes: 2