I want to delete image that I saved in cloudinary. I read docs and they said create an api endpoint to delete the image. I did it and it didnt work. This is my code:
api/admin/cloudinary/removeImage/route.js
import { cloudinary } from "@/backend/utils/cloudinary"
export async function POST(req, res) {
console.log('???? ~ POSTCloud ~ req:', req);
console.log('???? ~ POSTCloud ~ req.body:', req.body);
try {
const { public_id } = req.body;
await cloudinary.uploader.destroy(public_id);
res.status(200).json({ message: 'Image deleted successfully from Cloudinary' });
} catch (error) {
console.log('???? ~ POST ~ error:', error);
res.status(500).json({ error: 'Something went wrong!' });
}
}
and this is frontend code:
import React, { useState } from "react"
import { Plus, Trash } from "lucide-react"
import Image from "next/image"
import axios from "axios"
import { CldUploadWidget } from 'next-cloudinary'
const ImageUpload = ({ onChange, onRemove, value }) => {
const onUpload = (result) => {
onChange(result.info.secure_url)
}
const removeFromCloudinary = async (publicId) => {
console.log('???? ~ removeFromCloudinary ~ TypeOfpublicId:', typeof publicId)
try {
console.log('???? ~ removeFromCloudinary ~ publicId:', publicId)
const response = await axios.post(`${process.env.NEXT_PUBLIC_API_URL}/api/admin/cloudinary/removeImage`, { public_id: publicId })
console.log('Image removed from Cloudinary')
console.log('???? ~ removeFromCloudinary ~ response:', response.data)
} catch (error) {
console.error('Error removing image from Cloudinary:', error)
}
}
const handleRemove = async (url) => {
try {
const publicId = url.split('/').pop().replace(/.[^/.]+$/, "");
console.log('Public ID:', publicId);
await removeFromCloudinary(publicId);
onRemove(url);
} catch (error) {
console.error('Error removing image:', error);
}
}
return (
<div className="">
<div className="mb-4 flex flex-wrap items-center gap-4">
{value.map((url) => (
<div key={url} className="relative w-[200px] h-[200px]">
<div className="absolute top-0 right-4 z-10">
<button
type="button"
onClick={() => handleRemove(url)}
className="bg-red-500 p-2 rounded-md text-white"
>
<Trash className="h-4 w-4" />
</button>
</div>
<Image src={url} alt="collection" className="object-cover rounded-lg" fill />
</div>
))}
</div>
<CldUploadWidget uploadPreset="ml_default" onUpload={onUpload}>
{({ open }) => {
return (
<button type="button" onClick={() => open()} className="bg-gray-600 text-white flex items-center gap-1 p-3 rounded-md hover:bg-gray-700">
<Plus className="h-6 w-6 mr-2" />
<p>Upload Image</p>
</button>
)
}}
</CldUploadWidget>
</div>
)
}
export default ImageUpload
I log the req.body in API and I received: ReadableStream { locked: false, state: ‘readable’, supportsBYOB: false }
and log of req like
???? ~ POSTCloud ~ req: NextRequest [Request] {
[Symbol(realm)]: {
settingsObject: { baseUrl: undefined, origin: [Getter], policyContainer: [Object] }
},
[Symbol(state)]: {
method: 'POST',
localURLsOnly: false,
unsafeRequest: false,
body: { stream: undefined, source: null, length: null },
client: { baseUrl: undefined, origin: [Getter], policyContainer: [Object] },
reservedClient: null,
replacesClientId: '',
window: 'client',
keepalive: false,
serviceWorkers: 'all',
initiator: '',
destination: '',
priority: null,
origin: 'client',
policyContainer: 'client',
referrer: 'client',
referrerPolicy: '',
mode: 'cors',
useCORSPreflightFlag: true,
credentials: 'same-origin',
useCredentials: false,
cache: 'default',
redirect: 'follow',
integrity: '',
cryptoGraphicsNonceMetadata: '',
parserMetadata: '',
reloadNavigation: false,
historyNavigation: false,
userActivation: false,
taintedOrigin: false,
redirectCount: 0,
responseTainting: 'basic',
preventNoCacheCacheControlHeaderModification: false,
done: false,
timingAllowFailed: false,
headersList: _HeadersList {
cookies: null,
[Symbol(headers map)]: [Map],
[Symbol(headers map sorted)]: [Array]
},
urlList: [ URL {} ],
url: URL {
href: 'http://localhost:3000/api/admin/cloudinary/removeImage',
origin: 'http://localhost:3000',
protocol: 'http:',
username: '',
password: '',
host: 'localhost:3000',
hostname: 'localhost',
port: '3000',
pathname: '/api/admin/cloudinary/removeImage',
search: '',
searchParams: URLSearchParams {},
hash: ''
}
},
[Symbol(signal)]: AbortSignal { aborted: false },
[Symbol(abortController)]: AbortController { signal: AbortSignal { aborted: false } },
[Symbol(headers)]: _HeadersList {
cookies: null,
[Symbol(headers map)]: Map(21) {
'accept' => [Object],
'accept-encoding' => [Object],
'accept-language' => [Object],
'connection' => [Object],
'content-length' => [Object],
'content-type' => [Object],
'cookie' => [Object],
'host' => [Object],
'origin' => [Object],
'referer' => [Object],
'sec-ch-ua' => [Object],
'sec-ch-ua-mobile' => [Object],
'sec-ch-ua-platform' => [Object],
'sec-fetch-dest' => [Object],
'sec-fetch-mode' => [Object],
'sec-fetch-site' => [Object],
'user-agent' => [Object],
'x-forwarded-for' => [Object],
'x-forwarded-host' => [Object],
'x-forwarded-port' => [Object],
'x-forwarded-proto' => [Object]
},
[Symbol(headers map sorted)]: [
[Array], [Array], [Array],
[Array], [Array], [Array],
[Array], [Array], [Array],
[Array], [Array], [Array],
[Array], [Array], [Array],
[Array], [Array], [Array],
[Array], [Array], [Array]
]
},
[Symbol(internal request)]: {
cookies: RequestCookies { _parsed: [Map], _headers: [_HeadersList] },
geo: {},
ip: undefined,
nextUrl: NextURL { [Symbol(NextURLInternal)]: [Object] },
url: 'http://localhost:3000/api/admin/cloudinary/removeImage'
}
}