react-shop-web/front & back

모든 상품 정보를 데이터베이스에 저장하기

tjdvyzl 2023. 1. 23. 03:19

Product Model 만들기


models 폴더에 Product.js 파일 하나를  만든다.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const productSchema = mongoose.Schema({
    writer: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    title: {
        type: String,
        maxlength: 50
    },
    description: {
        type:String
    },
    price: {
        type: Number,
        default: 0
    },
    images: {
        type: Array,
        default:[]
    },
    sold: {
        type: Number,   
        maxlength: 100,
        default: 0
    },
    views: {
        type: Number,
        default: 0
    }
}, {timestamps: true})


const Product = mongoose.model('Product', productSchema);

module.exports = { Product }

models/Product.js

 


onSubmit Function 만들기 & 모든 정보 서버에 보내기


UploadProductPage.js 에서 Form태그의 onSubmit 이벤트와 버튼의 onClick 이벤트에 submitHandler라는 함수를 넣어주자.

 

  const submitHandler = (e) => {
    e.preventDefault();
    
    if (!Name || !Description || !Price || !Continent || !Images) {
      return alert('모든 값을 넣어주세요')
    }

    const body = {
      // writer의 값은 현재 로그인된 유저의 id이다.
      // 이거를 가져올 때 리덕스에 보면 현재 로그인된 사람의 id가 있는데 이것을 갖고와도 되고
      // auth.js에서 유저의 모든 정보를 넣어줬었는데 이거를 가져와도 된다. 강의에선 후자의 방식으로 진행
      // hoc를 이용하여 App.js에서 UploadProductPage 컴포넌트를 Auth로 묶어줬었다. 
      // 그래서 매개변수로 props를 갖고온다면 auth에서 저장했었던 유저의 모든 정보를 갖고올 수 있다.
      writer: props.user.userData._id,
      name: Name,
      description: Description,
      price: Price,
      images: Images,
      continents: Continent
    }

    //서버에 채운 값들을 request로 보낸다.
    Axios.post('/api/product', body)
      .then(response => {
        if (response.data.success) {
          alert('상품 업로드 성공');
          props.history.push('/')
        } else {
          alert('상품 업로드 실패')
        }
      })
  }

UploadProductPage.js 에서 submitHandler 구현부분 

 

위 코드에서 props.history.push 함수를 썼는데 

import { withRouter } from "react-router-dom";

이 코드를 갖고온 후에

맨 밑에 exports 하는 부분에 UploadProduct 부분을 withRouter()로 묶어줘야 오류가 안난다.

 

export default withRouter(UploadProductPage)

보내진 정보를 몽고DB에 저장하기


 

const express = require('express');
const router = express.Router();
const multer = require('multer')
const {Product} = require('../models/Product')

//=================================
//             Product
//=================================

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        // 밑에처럼 설정해주면 모든 파일이 uploads 폴더에 저장된다.
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, `${Date.now()}_${file.originalname}`) 
  }
})

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

router.post('/image', (req, res) => {

    // 가져온 이미지를 저장 해주는 부분 
    upload(req, res, err => {
        if(err){
            return res.json({success: false, err})
        }
        // 백엔드에서 파일 저장과 파일 저장 정보를 전달해주는데
        // 파일을 어디다가 저장했는지, 파일 이름은 무엇으로 정했는지 이 두가지를 client에 전달한다. 
        return res.json({success:true, filePath:res.req.file.path, fileName:res.req.filename})
    })
})


// UploadProductPage.js에서 api endPoint를 /api/product 로 요청을 보냈었다.
// index.js에서 product라는 라우트를 따로 만들어줬기 때문에 여기에서 end point는 '/'로 주면 된다.
router.post('/', (req, res) => {
    
    // 받아온 정보들을 DB에 넣어준다.

    // 넣어주기 전에 Product 모델을 갖고와야 한다.
    const product = new Product(req.body)

    product.save((err) => {
        if (err) return res.status(400).json({ success: false })
        return res.status(200).json({success:true})
    })
    
})

module.exports = router;

server/routes/product.js