简体   繁体   中英

How to fix multer code not adding to my created folder inside my server in nodejs with reactjs frontend

I'm trying to upload a photo in my server folder but when I try to submit it, it doesn't show any picture. It is successfully adding to my database but the picture that I'm trying to upload doesn't show up on my server folder. I'm using React JS as my frontend and I don't get why it is not working. I'm a beginner and I don't know if I'm doing it right. Below is my code.

Multer Code

const path = require('path');
const multer = require('multer');

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, '../Bicycles')
    },
    filename: (req, file, cb) => {
        console.log(file);
        cb(null,file.fieldname + "-" + Date.now() + path.extname(file.originalname));
    }
})

const upload = multer({ storage: storage }).single("image");

module.exports = upload;

admin route

const router = express.Router();
const upload = require('../Middlewares/uploadMiddleware');

const adminController = require('../controllers/adminController');

const { validateToken } = require('../Middlewares/authAdminMiddleware');
router.get('/admin/auth',validateToken,adminController.adminAuth_get);


router.get('/admins', adminController.admin_get);
router.post('/admin/register',adminController.admin_register);
router.post('/admin/login',adminController.admin_login);
router.get('/admin/logout',adminController.admin_logout);
router.post('/admin/addproduct',upload,adminController.admin_addproduct);


module.exports = router; 

Adding product controller

const admin_addproduct = (req, res) => {
    const { image, brand, item, quantity, description } = req.body;

   Product.create({
      image,
      brand,
      item,
      quantity,
      description  
   })
   .then((product) => {
       res.status(200).json({ product, success: 'Successfully added!' })
   })
   .catch((err) => console.log(err))
}

React JS frontend

import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { AiOutlineLeft } from 'react-icons/ai';
import { FiPlus } from 'react-icons/fi';
import LogoutModal from '../modals/LogoutModal';
import Axios from 'axios';
import { useState } from 'react';

const AddProduct = ({ date,logoutMssg }) => {
    const [image,setImage] = useState('');
    const [brand,setBrand] = useState('');
    const [item,setItem] = useState('');
    const [quantity,setQuantity] = useState('');
    const [description,setDescription] = useState('');

    const [showImage,setShowImage] = useState(false);
    const [imageHolder,setImageHolder] = useState('');

    const onSubmit = (e) => {
        e.preventDefault();

        const formData = new FormData();
        formData.append("image", image);
        formData.append("brand",brand);
        formData.append("item",item);
        formData.append("quantity", quantity);
        formData.append("description",description);

        Axios.post('/api/admin/addproduct',formData)
            .then((res) => {
                console.log(res);
            })
    }

    // previews image before uploading
    const imageHandler = (e) => {
        const reader = new FileReader();
        reader.onload = () => {
            if(reader.readyState === 2) {
                setImageHolder(reader.result);
                setShowImage(true);
            }
        }
        reader.readAsDataURL(e.target.files[0]);
        setImage(e.target.value);
    }

    return (
        <div className="flex justify-center">
        <Helmet><title>Bicycle System | Add Products</title></Helmet>
            <div className="max-w-7xl w-full">
                <div className="flex items-center justify-between py-5">
                    <Link className="flex items-center text-xl font-semibold" to='/dashboard'><AiOutlineLeft />Go Back</Link>
                    <label htmlFor="date">{date}</label>
                </div>
                
                <form onSubmit={onSubmit} className="px-16 py-14">
                    <h1 className="text-3xl font-bold p-2 border-b-2 border-gray-300">Add Product</h1>

                    <div className="py-2 px-2 flex gap-10">
                        <div className="max-h-60 border p-20 flex items-center justify-center relative bg-gray-50">
                            <input value={image} name="image" onChange={imageHandler} 
                            className="opacity-0 w-64 h-60 absolute cursor-pointer" type="file" accept="image/*" required/>
                           { showImage ? 
                            <img className="object-cover w-64" src={imageHolder} alt="cover" /> 
                            :
                            <label className="flex justify-center items-center flex-col" htmlFor="file">
                                <FiPlus size="100px" />
                                Add Photo
                            </label>  
                            }
                        </div>
                        
                        <div className="flex flex-col">
                            <div className="flex flex-col">
                                <label htmlFor="brandname">Brand Name</label>
                                <input className="border border-gray-400 w-60 outline-none" type="text" required 
                                    value={brand} onChange={(e) => setBrand(e.target.value)}
                                />
                            </div>
                            <div className="flex flex-col">
                                <label htmlFor="brandname">Item Name</label>
                                <input className="border border-gray-400 w-60 outline-none" type="text" required 
                                     value={item} onChange={(e) => setItem(e.target.value)}
                                />
                            </div>
                            <div className="flex flex-col">
                                <label htmlFor="brandname">Quantity</label>
                                <input className="w-28 border border-gray-400 outline-none" type="number" required 
                                     value={quantity} onChange={(e) => setQuantity(e.target.value)}
                                />
                            </div>
                        </div>

                        <div className="w-full relative">
                            <div className="flex-col flex">
                                <label htmlFor="description">Item Description</label>
                                <textarea className="w-full border border-gray-400 outline-none h-32" id=""
                                 value={description} onChange={(e) => setDescription(e.target.value)}></textarea>
                                <button className="absolute bottom-5 text-gray-100 p-2 bg-gray-900 rounded-md">Add Product</button>
                            </div>
                        </div>
                    </div>
                </form>
                
            </div>
            {/* modal when logging out */}
            { logoutMssg && <LogoutModal /> }
        </div>
    )
}

export default AddProduct

Create a folder- images, in the root directory. Then implement code as follows:

const imageStorage = multer.diskStorage({
    // Destination to store image     
    destination: 'images', 
      filename: (req, file, cb) => {
          cb(null, file.fieldname + '_' + Date.now() 
             + path.extname(file.originalname))
            // file.fieldname is name of the field (image)
            // path.extname get the uploaded file extension
    }
});

Destination is used so that the application can know where to store images. It can be a string (eg './upload'). The default directory for all the temporary files is used in case the destination is not provided. Creating a directory is compulsory when you use the destination as a function. Or else, if you use destination as string, Multer will create directory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM