Cloudinary

Suppose you want to upload a user avatar to cloudinary and store the url to your database.
            
In Backend-
1.Create a cloudinary.js and multer.js file. CLOUD_NAME, CLOUD_API_KEY, CLOUD_API_SECRET will be provided once you sign up on cloudinary.
cloudinary.js-
const cloudinary = require("cloudinary").v2; const path = require("path"); require("dotenv").config({ path: path.resolve(__dirname, "../config/config.env"),}); cloudinary.config({ cloud_name: process.env.CLOUD_NAME, api_key: process.env.CLOUD_API_KEY, api_secret: process.env.CLOUD_API_SECRET,}); module.exports=cloudinary
multer.js-
const Multer = require("multer"); const storage = new Multer.memoryStorage(); const upload = Multer({storage}); module.exports=upload
2. in userRoutes- we're sending userName and avatar from frontend. Both of the names should match with what's given in the schema of user.
const router=express.Router() const upload = require("./../utils/multer"); router.route("/registerUser").post( upload.fields([ { name: "userName", maxCount: 1 }, { name: "avatar", maxCount: 1 },]) userController.registerUser);
3. in userController-
const cloudinary = require("./../utils/cloudinary.js"); const streamifier = require("streamifier"); //upload avatar to cloudinary const bufferStream=streamifier.createReadStream(req.files.avatar[0].buffer) const result = await new Promise((resolve, reject) => { const cloudStream = cloudinary.uploader.upload_stream( { folder: "BuyBud/users" }, (error, result) => { if (error) {reject(error)} else {resolve(result)}}); bufferStream.pipe(cloudStream) // Pipe the buffer stream to the cloudinary upload stream }) ; let avatar = { public_id: result.public_id, url: result.url,}
you can now send the userName and avatar to be saved in database
user = new User({ userName, avatar}); await user.save();
for multiple images-
let imageUrls = []; const { title, description, price, category, stock } = req.body; for (let i = 0; i < req.files.imageUrls.length; i++) { const bufferStream = streamifier.createReadStream( req.files.imageUrls[i].buffer ); // Create a readable stream from the buffer const result = await new Promise((resolve, reject) => { const cloudStream = cloudinary.uploader.upload_stream( { folder: "BuyBud/products" }, (error, result) => { if (error) {reject(error)} else {resolve(result)}}); bufferStream.pipe(cloudStream); // Pipe the buffer stream to the cloudinary upload stream }) imageUrls.push({ public_id: result.public_id, url: result.url})}
            
In Frontend-
4. In your react component- in return statement, provide space for user to upload the image-
<label>Avatar:</label> <input type="file" onChange={handleAvatarUpload} /> (add multiple for image array)
above return statement, handle the logic to send the avatar to backend. set the avatar to avatar variable
const [avatar, setAvatar] = useState(null); const handleAvatarUpload = (e) => { setAvatar(e.target.files)};
use axios to send formData to request url. The name `avatar` should be the same as backend.
let formData = new FormData(); formData.append("userName", userName); formData.append(`avatar`, avatar); const response = await axios.post("/api/registerUser", formData, { headers: { "Content-Type": "multipart/form-data"}});
for array- (`imageUrls`) name should be the same as is in the backend
let handleImageUpload=(e)=>{ setImageFiles(e.target.files)} for (let i = 0; i < imageFiles.length; i++) {formData.append(`imageUrls`, imageFiles[i])}