Roman
Roman

Reputation: 147

Uploading Data including a file is causing an error

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

Answers (1)

yashlodhi
yashlodhi

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

Related Questions