In this article we will upload, retrieve, update and delete images from Cloudinary. For that, we will use nodejs, express, multer, cloudinary and also mongoDB as our database.
If you prefer watching video tutorial then watch this:
or you may continue reading. First of all create project directory, open this directory in code editor. Now we will initialize package.json file. Open your terminal and run
npm init -y
After that we will install a few dependencies.
npm install express mongoose cloudinary multer dotenv
Optionally, I will also install nodemon as dev dependency to constantly watch server.
npm install -D nodemon
Now within package.json inside "scripts", add
"server": "nodemon index"
Now we will setup basic express server. Create index.js file and paste the following code.
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
dotenv.config();
// Connect DB
mongoose
.connect(process.env.MONGO_URI, {
useCreateIndex: true,
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
})
.then(() => console.log("mongoDB is connected"))
.catch((err) => console.log(err));
// Middleware
app.use(express.json());
app.listen(5000, () => console.log("Server is running"));
Create .env file and add
MONGO_URI=path-to-your-mongodb
Open terminal and type npm run server
to see if everything is working fine.
Lets create a folder at root level models and inside models create a file user.js and paste the following code
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {
type: String,
},
avatar: {
type: String,
},
cloudinary_id: {
type: String,
},
});
module.exports = mongoose.model("User", userSchema);
Here we have defined three fields, name, avatar and cloudinary_id. We will need cloudinary_id when we will send put / delete request later.
Go to Cloudinary website and register / login. You will be redirected to your dashboard where under Account Details you will find your Cloud Name, API Key and API Secret. Copy their values and inside .env file create 3 variables to store those values
CLOUD_NAME=YOUR-CLOUD-NAME
API_KEY=YOUR-API-KEY
API_SECRET=YOUR-API-SECRET
Now create a folder at root level utils and create 2 files inside this folder, cloudinary.js and multer.js. Here we will configure cloudinary and multer. Inside cloudinary.js paste the following code
const cloudinary = require("cloudinary").v2;
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET,
});
module.exports = cloudinary;
Inside multer.js paste the following code.
const multer = require("multer");
const path = require("path");
// Multer config
module.exports = multer({
storage: multer.diskStorage({}),
fileFilter: (req, file, cb) => {
let ext = path.extname(file.originalname);
if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") {
cb(new Error("File type is not supported"), false);
return;
}
cb(null, true);
},
});
Here we have required multer and nodejs core module path. We required path to extract file extension in order to filter files we want to allow.
Go to index.js and before listening to server, add
// Route
app.use('/user', require('./routes/user'))
Let's create a folder at root level routes and inside routes create file user.js. Now we will send a post request to upload image to cloudinary. Inside user.js file paste the following
const router = require("express").Router();
const cloudinary = require("../utils/cloudinary");
const upload = require("../utils/multer");
const User = require("../model/user");
router.post("/", upload.single("image"), async (req, res) => {
try {
// Upload image to cloudinary
const result = await cloudinary.uploader.upload(req.file.path);
// Create new user
let user = new User({
name: req.body.name,
avatar: result.secure_url,
cloudinary_id: result.public_id,
});
// Save user
await user.save();
res.json(user);
} catch (err) {
console.log(err);
}});
module.exports = router;
Here we required express router, from utils folder cloudinary and multer and User model. We are uploading single image so right after router url, we have specified upload.single('image').
We used cloudinary.uploader.upload and pass the file path to upload method to get the image. We stored the response we got back from cloudinary into result variable. It will be an object and we will use two properties secure_url and public_id.
After the image is uploaded, we created new instance of user. name will be provided in req.body, avatar and cloudinary_id values will be result.secure_url and result.public_id respectively.
Now go to postman make a POST request to http://localhost:5000/user provide name and image in form-data and hit SEND. Navigate to "Media Library" in your cloudinary account you will find the image you just uploaded.
Let's make a GET request, go to user.js and paste the following
router.get("/", async (req, res) => {
try {
let user = await User.find();
res.json(user);
} catch (err) {
console.log(err);
}});
DELETE request
router.delete("/:id", async (req, res) => {
try {
// Find user by id
let user = await User.findById(req.params.id);
// Delete image from cloudinary
await cloudinary.uploader.destroy(user.cloudinary_id);
// Delete user from db
await user.remove();
res.json(user);
} catch (err) {
console.log(err);
}});
First find user by id, after that we are deleting file from cloudinary. destroy method takes public_id as argument, we have stored public_id as cloudinary_id into our DB
PUT request
router.put("/:id", upload.single("image"), async (req, res) => {
try {
let user = await User.findById(req.params.id);
// Delete image from cloudinary
await cloudinary.uploader.destroy(user.cloudinary_id);
// Upload image to cloudinary
const result = await cloudinary.uploader.upload(req.file.path);
const data = {
name: req.body.name || user.name,
avatar: result.secure_url || user.avatar,
cloudinary_id: result.public_id || user.cloudinary_id,
};
user = await User.findByIdAndUpdate(req.params.id, data, {
new: true
});
res.json(user);
} catch (err) {
console.log(err);
}});
First find user by id, then delete the existing image from cloudinary. After that upload the new image to cloudinary and update the data with the updated secure_url and public_id into our database as avatar and cloudinary_id
So thats how we can perform CRUD operations on cloudinary with nodejs multer and cloudinary.
Top comments (5)
Hi, I followed your code samples but i am getting the following errors on the console. Can you help out?
var useAgent = navigator && navigator.userAgent || '';
^
ReferenceError: navigator is not defined
at Module../src/namespace/cloudinary-core.js (C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:1168:16)
at webpack_require (C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:37:30)
at C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:101:18
at C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:104:10
at webpackUniversalModuleDefinition (C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:10:20)
at Object. (C:\Users\DeveloperEmpier\Desktop\test-bk\node_modules\cloudinary-core\cloudinary-core.js:17:3)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
Great article !!...helped me at the right time :)
Thanks for this post. It really helped me.
Each line of code worked well.
How would you upload multiple images to cloudinary?
Try 'array' instead 'single'.
Don't forget to specify the limit in the parameters.