I can successfully upload an image using the multer-storage-cloudinary package but I have not pieced together an implementation for how to destroy the image in cloudinary from my update or delete route. All resources I have found only reference uploading images. Here is what I have to upload the image
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const multer = require('multer');
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET
});
const storage = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: "works",
allowedFormats: ["jpg", "png"]
}
});
const imgUpload = multer({ storage: storage });
router.post('/', withAuth, imgUpload.single('work-img'), (req, res) => {
console.log(req.file);
Post.create({
title : req.body.title,
dimension : req.body.dimensions,
description : req.body.description,
media : req.body.media,
img_url : req.file.path,
user_id : req.session.user_id
})
.then((dbPostData) => res.json(dbPostData))
.catch((err) => {
console.log(err);
res.status(500).json(err);
});
});
Here is the front-end code that handles the form submission
async function newFormHandler(event) {
event.preventDefault();
const form = document.querySelector('#new-post-form');
const formData = new FormData(form);
const response = await fetch(`/api/posts`, {
method : 'POST',
body : formData
});
if (response.ok) {
document.location.replace('/dashboard');
} else {
alert(response.statusText);
}
}
document.querySelector('#new-post-form').addEventListener('submit', newFormHandler);
And finally my update route which works to upload a new image and save it's new path to the database, but I also want to remove the old image from Cloudinary so I don't have unused artifacts building up there.
router.put('/:id', withAuth, imgUpload.single('work-img'), (req, res) => {
Post.update(
{
title : req.body.title,
dimension : req.body.dimensions,
description : req.body.description,
media : req.body.media,
img_url : req.file.path
},
{
where : {
id : req.params.id
}
}
)
.then((dbPostData) => {
if (!dbPostData) {
res.status(404).json({ message: 'No post found with this id' });
return;
}
res.json(dbPostData);
})
.catch((err) => {
console.log(err);
res.status(500).json(err);
});
});
If I look at the console.log(req.file) in the post route, it gives me something like this
{
fieldname: 'work-img',
originalname: '20171005_134508.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
path: 'https://res.cloudinary.com/xxxxxxxxx/image/upload/xxxxxxxx/works/ujrrf13kyil8l5rjccwf.jpg',
size: 3647252,
filename: 'works/ujrrf13kyil8l5rjccwf'
}
{
"public_id": "eneivicys42bq5f2jpn2",
"version": 1570979139,
"signature": "abcdefghijklmnopqrstuvwxyz12345",
"width": 1000,
"height": 672,
"format": "jpg",
"resource_type": "image",
"created_at": "2017-08-11T12:24:32Z",
"tags": [],
"bytes": 350749,
"type": "upload",
"etag": "5297bd123ad4ddad723483c176e35f6e",
"url": "http://res.cloudinary.com/demo/image/upload/v1570979139/eneivicys42bq5f2jpn2.jpg",
"secure_url": "https://res.cloudinary.com/demo/image/upload/v1570979139/eneivicys42bq5f2jpn2.jpg",
"original_filename": "sample",
"eager": [
{ "transformation": "c_pad,h_300,w_400",
"width": 400,
"height": 300,
"url": "http://res.cloudinary.com/demo/image/upload/c_pad,h_300,w_400/v1570979139/eneivicys42bq5f2jpn2.jpg",
"secure_url": "https://res.cloudinary.com/demo/image/upload/c_pad,h_300,w_400/v1570979139/eneivicys42bq5f2jpn2.jpg" },
I could then use 'public_id' with the destroy method like so, but I don't have access to the public_id to configure this: cloudinary.v2.uploader.destroy(public_id, options, callback);
I am unclear how to implement this or if it is even possible using the multer-storage-cloudinary package