'How to Use Multer and Fileupload Both in Node js For uploading Images Using Cloudinary

I want a solution about how can I use both packages express-fileupload and multer for uploading images I am trying to use both simultaneously but when I post a post on my website then it caught me error but when I comment out below line then it works

const express = require("express");
const fileUpload = require('express-fileupload');
const app = express();

app.use(fileUpload({
  useTempFiles: true
}));

But for users, it does not change the user avatar on my website how can I solve this problem by using only multer?

Server.js (Backend)

const dotenv = require('dotenv');
const express = require("express");
const bodyparser = require('body-parser');
const connectDB = require('./config/db');
const cors = require('cors');
const errorHandler = require("./middleware/error");
const fileUpload = require('express-fileupload');
const cookieParser = require('cookie-parser');

const app = express();

app.use(bodyparser.json());
app.use(cors());
app.use(cookieParser());

app.use(fileUpload({
  useTempFiles: true
}));

app.use('/', express.static('uploads'));
app.use(bodyparser.urlencoded({ extended: false }));

app.get("/", (req, res, next) => {
  res.send("Api running");
});

// Connecting Routes
app.use('/', require('./routes/indexpost'));
app.use('/user', require('./routes/userRouter'));
app.use('/api', require('./routes/upload'));
app.use("/comments", require("./controllers/Comments"));

// app.use('/comments', require('./routes/Comments'));

// Error Handler Middleware
app.use(errorHandler);

// load config
dotenv.config();

connectDB();

const PORT = process.env.PORT || 5000;

app.listen(PORT, () =>
  console.log(`Sever running on port ${PORT}`)
);

Upload.js (Backend)

const router = require('express').Router()
const uploadImage = require('../middleware/uploadImage')
const uploadCtrl = require('../controllers/uploadCtrl')
const auth = require('../middleware/auth')

router.post('/upload_avatar', uploadImage, auth, uploadCtrl.uploadAvatar)

module.exports = router

uploadimage.js

const fs = require('fs');

module.exports = async function(req, res, next) {
    try {
        if(!req.files || Object.keys(req.files).length === 0)
            return res.status(400).json({msg: "No files were uploaded."})
            
        const file = req.files.file;

        if(file.size > 1024 * 1024){
            removeTmp(file.tempFilePath)
            return res.status(400).json({msg: "Size too large."})
        } // 1mb

        if(file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png'){
            removeTmp(file.tempFilePath)
            return res.status(400).json({msg: "File format is incorrect."})
        }

        next()
    } catch (err) {
        return res.status(500).json({msg: err.message})
    }
}

const removeTmp = (path) => {
    fs.unlink(path, err => {
        if(err) throw err
    })
}

uploadCtrl.js

const cloudinary = require('cloudinary')
const fs = require('fs')

cloudinary.config({
    cloud_name: process.env.CLOUD_NAME,
    api_key: process.env.CLOUD_API_KEY,
    api_secret: process.env.CLOUD_API_SECRET
})

console.log(process.env.api_secret);


const uploadCtrl = {
    uploadAvatar: (req, res) => {
        try {
            const file = req.files.file;
            
            cloudinary.v2.uploader.upload(file.tempFilePath, {
                folder: 'avatar', width: 150, height: 150, crop: "fill"
            }, async(err, result) => {
                if(err) throw err;

                removeTmp(file.tempFilePath)

                res.json({url: result.secure_url})
            })
        
        } catch (err) {
            return res.status(500).json({msg: err.message})
        }
    }

}


const removeTmp = (path) => {
    fs.unlink(path, err => {
        if(err) throw err
    })
}

module.exports = uploadCtrl

Profile.js (Client)

import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { useSelector, useDispatch } from 'react-redux'
import { Link } from 'react-router-dom'
import { isLength, isMatch } from '../../utils/validation/Validation'
import { showSuccessMsg, showErrMsg } from '../../utils/notification/Notification'
import { fetchAllUsers, dispatchGetAllUsers } from '../../../redux/actions/usersAction'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import './profile.css'

const initialState = {
    name: '',
    password: '',
    cf_password: '',
    err: '',
    success: ''
}

function Profile() {
    const auth = useSelector(state => state.auth)
    const token = useSelector(state => state.token)

    const users = useSelector(state => state.users)

    const { user, isAdmin } = auth
    const [data, setData] = useState(initialState)
    const { name, password, cf_password, err, success } = data

    const [avatar, setAvatar] = useState(false)
    const [loading, setLoading] = useState(false)
    const [callback, setCallback] = useState(false)

    const dispatch = useDispatch()

    useEffect(() => {
        if (isAdmin) {
            fetchAllUsers(token).then(res => {
                dispatch(dispatchGetAllUsers(res))
            })
        }
    }, [token, isAdmin, dispatch, callback])

    const handleChange = e => {
        const { name, value } = e.target
        setData({ ...data, [name]: value, err: '', success: '' })
    }

    const changeAvatar = async (e) => {
        e.preventDefault()
        try {
            const file = e.target.files[0]

            if (!file) return setData({ ...data, err: "No files were uploaded.", success: '' })

            if (file.size > 1024 * 1024)
                return setData({ ...data, err: "Size too large.", success: '' })

            if (file.type !== 'image/jpeg' && file.type !== 'image/png')
                return setData({ ...data, err: "File format is incorrect.", success: '' })

            let formData = new FormData()
            formData.append('file', file)

            setLoading(true)
            const res = await axios.post('/api/upload_avatar', formData, {
                headers: { 'content-type': 'multipart/form-data', Authorization: token }
            })

            setLoading(false)
            setAvatar(res.data.url)

        } catch (err) {
            setData({ ...data, err: err.response.data.msg, success: '' })
        }
    }

    const updateInfor = () => {
        try {
            axios.patch('/user/update', {
                name: name ? name : user.name,
                avatar: avatar ? avatar : user.avatar
            }, {
                headers: { Authorization: token }
            })

            setData({ ...data, err: '', success: "Updated Success!" })
        } catch (err) {
            setData({ ...data, err: err.response.data.msg, success: '' })
        }
    }

    const updatePassword = () => {
        if (isLength(password))
            return setData({ ...data, err: "Password must be at least 6 characters.", success: '' })

        if (!isMatch(password, cf_password))
            return setData({ ...data, err: "Password did not match.", success: '' })

        try {
            axios.post('/user/reset', { password }, {
                headers: { Authorization: token }
            })

            setData({ ...data, err: '', success: "Updated Success!" })
        } catch (err) {
            setData({ ...data, err: err.response.data.msg, success: '' })
        }
    }

    const handleUpdate = () => {
        if (name || avatar) updateInfor()
        if (password) updatePassword()
    }

    const handleDelete = async (id) => {
        try {
            if (user._id !== id) {
                if (window.confirm("Are you sure you want to delete this account?")) {
                    setLoading(true)
                    await axios.delete(`/user/delete/${id}`, {
                        headers: { Authorization: token }
                    })
                    setLoading(false)
                    setCallback(!callback)
                }
            }

        } catch (err) {
            setData({ ...data, err: err.response.data.msg, success: '' })
        }
    }

    return (
        <>
            <div>
                {err && showErrMsg(err)}
                {success && showSuccessMsg(success)}
                {loading && <h3>Loading.....</h3>}
            </div>
            <div className="profile_page">
                <div className="profile_container">
                    <div className="col-left">
                        <h2>{isAdmin ? "Admin Profile" : "User Profile"}</h2>

                        <div className="avatar">
                            <img src={avatar ? avatar : user.avatar} alt="" />
                            <span>
                                <FontAwesomeIcon icon="fa-solid fa-camera" />
                                <p>Change</p>
                                <input type="file" name="file" id="file_up" onChange={changeAvatar} />
                            </span>
                        </div>

                        <div className="form-group">
                            <label htmlFor="name">Name</label>
                            <input type="text" name="name" id="name" defaultValue={user.name}
                                placeholder="Your name" onChange={handleChange} />
                        </div>

                        <div className="form-group">
                            <label htmlFor="email">Email</label>
                            <input type="email" name="email" id="email" defaultValue={user.email}
                                placeholder="Your email address" disabled />
                        </div>

                        <div className="form-group">
                            <label htmlFor="password">New Password</label>
                            <input type="password" name="password" id="password"
                                placeholder="Your password" value={password} onChange={handleChange} />
                        </div>

                        <div className="form-group">
                            <label htmlFor="cf_password">Confirm New Password</label>
                            <input type="password" name="cf_password" id="cf_password"
                                placeholder="Confirm password" value={cf_password} onChange={handleChange} />
                        </div>

                        <div>
                            <em style={{ color: "crimson" }}>
                                * If you update your password here, you will not be able
                                to login quickly using google.
                            </em>
                        </div>

                        <button disabled={loading} onClick={handleUpdate}>Update</button>
                    </div>
                </div>

                <div className="col-right">
                    <h2>{isAdmin ? "Users" : ""}</h2>
                    {isAdmin ?
                        <div style={{ overflowX: "auto" }}>
                            <table className="customers">
                                <thead>
                                    <tr>
                                        <th>ID</th>
                                        <th>Name</th>
                                        <th>Email</th>
                                        <th>Admin</th>
                                        <th>Action</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {
                                        users.map(user => (
                                            <tr key={user._id}>
                                                <td>{user._id}</td>
                                                <td>{user.name}</td>
                                                <td>{user.email}</td>
                                                <td>
                                                    {
                                                        user.role === 1
                                                            ? <FontAwesomeIcon icon="fa-solid fa-check" title="Admin" />
                                                            : <FontAwesomeIcon icon="fas fa-times" title="User" />
                                                    }
                                                </td>
                                                <td>
                                                    <Link to={`/edit_user/${user._id}`}>
                                                        <FontAwesomeIcon className='adminedit' icon="fas fa-edit" title="Edit" />
                                                    </Link>
                                                    <FontAwesomeIcon className='admindelete' icon="fa-solid fa-trash-can" title="Remove"
                                                        onClick={() => handleDelete(user._id)} />
                                                </td>
                                            </tr>
                                        ))
                                    }
                                </tbody>
                            </table>
                        </div> : ""}
                </div>
            </div>
        </>
    )
}

export default Profile

Here is my posts multer image in server.js

app.use('/', express.static('uploads'));


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source