Home > other >  How i can update the cloudinary image url and save into the database in nodejs and reactjs
How i can update the cloudinary image url and save into the database in nodejs and reactjs

Time:03-23

I'm creating a book project where i'm saving the books images into the cloudinary and there url's saving into the mongodb database which are working well.But i'm facing issue during the updation of a book when i update my book then the url of book is not updated and console giving me error Cannot read properties of undefined (reading 'map') where i want to update the url with new one url of image but its not working Please any one can solve this

this is my update.js code

module.exports.updateBook = async (req, res) => {
try {
  const { id } = req.params;
  const book = req.body;
  const singleBook = await Book.findById(id);
  // Delete Prvious Url From the Cloudinary and Reset It to the new ..
  cloudinary.v2.uploader.destroy(singleBook.image[0].filename);
  book.image = req.files.map((f) => ({
   url: f.path,
   filename: f.filename,
  }));
   console.log("Single Book ===", singleBook);
   const updateBook = await Book.findByIdAndUpdate(
    id,
    { $set: book },
    { new: true }
   );
  if (updateBook) {
    res
      .status(200)
      .json({ success: true, message: "Book Updated Successfully!" });
  } else {
     res.status(400).json({
     success: false,
     message: "Book Not Updated There Is an error!",
   });
  }
 } catch (err) {
   console.log("** Error In Update Book **", err.message);
 }
};

this is my route handler

const express = require("express");
const router = express.Router();
const book = require("../controller/book");
const authenticated = require("../middleware/verifyToken");
const multer = require("multer");
const { storage } = require("../cloudinary");
const upload = multer({ storage });

// Update Book By ID
router.route("/:id").put(authenticated, upload.array("image"), book.updateBook);
module.exports = router;

this is my reactjs update method

  const formik = useFormik({
   initialValues: {
    title: book?.title,
    author: book?.author,
    price: book?.price,
    description: book?.description,
    image: book?.image[0].url,
  },
validationSchema: validationSchema,
enableReinitialize: true,
    onSubmit: (values) => {
      const formData = new FormData();
      formData.append("title", values.title);
      formData.append("price", values.price);
      formData.append("description", values.description);
      formData.append("author", values.author);
      formData.append("image", values.image);
      Axios.put(`${Base_URL}/book/${id}`, values, {
        headers: {
        Authorization: authHeader(),
       },
      })
       .then((res) => {
        if (res.data.success) {
          message = res.data.message;
          setAlertContentupdate(message);
          setAlertupdate(true);
          setTimeout(() => {
           handleClose();
             navigate(`/book/${id}`);
           getBook();
           console.log("Response == ", res.data.message);
          }, 3000);
        }
      })
      .catch((err) => {
        console.log("Error ====", err.message);
       });
     },

this is my jsx code for updating book

 <form onSubmit={formik.handleSubmit}>
          <TextField
            name="title"
            autoFocus
            margin="dense"
            label="Book Title"
            type="text"
            fullWidth
            variant="standard"
            value={formik.values.title}
            onChange={formik.handleChange}
            error={formik.touched.title && Boolean(formik.errors.title)}
            helperText={formik.touched.title && formik.errors.title}
          />
          <TextField
            name="author"
            margin="dense"
            label="Book Author"
            type="text"
            fullWidth
            variant="standard"
            value={formik.values.author}
            onChange={formik.handleChange}
            error={formik.touched.author && Boolean(formik.errors.title)}
            helperText={formik.touched.author && formik.errors.author}
          />
          {/* File Input Field */}
          {/* Picture Input */}
          <input
            type="file"
            name="image"
            accept=".png, .jpeg, .jpg"
            onChange={(e) => {
              formik.setFieldValue("image", e.target.files[0]);
            }}
          />
          {formik.touched.image && formik.errors.image ? (
            <div style={{ color: "#e53935", fontSize: "12px" }}>
              {formik.errors.image}
            </div>
          ) : null}
          {/* Price Input Field */}
          <TextField
            name="price"
            margin="dense"
            label="Book Price"
            type="text"
            fullWidth
            variant="standard"
            value={formik.values.price}
            onChange={formik.handleChange}
            error={formik.touched.price && Boolean(formik.errors.price)}
            helperText={formik.touched.price && formik.errors.price}
          />
          <TextField
            name="description"
            margin="dense"
            label="Book Description"
            type="text"
            fullWidth
            variant="standard"
            value={formik.values.description}
            onChange={formik.handleChange}
            error={
              formik.touched.description &&
              Boolean(formik.errors.description)
            }
            helperText={
              formik.touched.description && formik.errors.description
            }
          />
          <DialogActions>
            <Button onClick={handleClose}>Cancel</Button>
            <Button type="submit">Update</Button>
          </DialogActions>
        </form>

In formik i'm getting the book data from back end api's and putting into the formik initial values But Problem is that when i clicked on the update button then the backend compiler giving me this error Cannot read properties of undefined (reading 'map') Please any one can solve this thanks in advance

CodePudding user response:

So this line looks like the issue for me:

cloudinary.v2.uploader.destroy(singleBook.image[0].filename);

Using this is actually deleting your asset so you are probably want to just update it using the explicit API. See https://cloudinary.com/documentation/image_upload_api_reference#explicit

So maybe something like:

cloudinary.v2.uploader.explicit(singleBook.image[0].filename);

Let me know if this helps?

  • Related