인프런 커뮤니티 질문&답변

yami654님의 프로필 이미지
yami654

작성한 질문수

비전공자를 위한 진짜 입문 올인원 개발 부트캠프

그랩마켓 최종 구현

에러가 발생합니다..ㅜ

작성

·

345

1

상품이미지 업로드하고 등록하기 누르면 메인화면으로 돌아가야하는데 에러메세지가 뜹니다.  어느부분이 잘못된걸까요..ㅜㅜ

아래는 server.js코드입니다.

const express = require("express");
const cors = require("cors");
const app = express();
const models = require("./models");
const multer = require("multer");
const upload = multer({
  storage: multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, "uploads/");
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname);
    },
  }),
});
const port = 8080;

app.use(express.json());
app.use(cors());
app.use("/uploads", express.static("uploads"));

app.get("/products", (req, res) => {
  models.Product.findAll({
    order: [["createdAt", "DESC"]],
    attributes: ["id", "name", "price", "createdAt", "seller", "imageUrl"],
  })
    .then((result) => {
      console.log("PRODUCTS: ", result);
      res.send({
        products: result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("에러 발생");
    });
});

app.post("/products", (req, res) => {
  const body = req.body;
  const { name, description, price, seller, imageUrl } = body;
  if (!name || !description || !price || !seller || imageUrl) {
    res.status(400).send("모든필드를 입력해주세요.");
  }
  models.Product.create({ description, price, seller, imageUrl, name })
    .then((result) => {
      console.log("상품 생성 결과 : ", result);
      res.send({
        result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("상품 업로드에 문제가 발생했습니다.");
    });
});

app.get("/products/:id", (req, res) => {
  const params = req.params;
  const { id } = params;
  models.Product.findOne({
    where: {
      id: id,
    },
  })
    .then((result) => {
      console.log("PRODUCTS :", result);
      res.send({
        product: result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("상품 조회에 에러가 발생했습니다.");
    });
});

app.post("/image", upload.single("image"), (req, res) => {
  const file = req.file;
  console.log(file);
  res.send({
    imageUrl: file.path,
  });
});

app.listen(port, () => {
  console.log("그랩의 쇼핑몰 서버가 돌아가고 있습니다.");
  models.sequelize
    .sync()
    .then(() => {
      console.log("DB 연결 성공!");
    })
    .catch((error) => {
      console.error(err);
      console.log("DB 연결 에러");
      process.exit();
    });
});

답변 6

0

yami654님의 프로필 이미지
yami654
질문자

아 드디어 해결했습니다. ㅜㅜ 저 빨간 부분에 imageUrl 앞에 ! 가 없어서 안됐던거였어요 ㅠㅠㅠㅠ

그랩님 답변보면서 다시 천천히 보다가 발견했어요ㅠㅠ 저기에 ! 붙히니까 return을 붙혀도 안붙혀도 다 정상 실행이 되더라구요!!! 

그동안 많은 질문에 답변 달아주셔서 감사합니다!!

아마 강의 끝날때 까지 질문 올릴거 같아요 ㅎ.ㅎ..

app.post("/products", (req, res) => {
  const body = req.body;
  const { name, description, price, seller, imageUrl } = body;
  if (!name || !description || !price || !seller || !imageUrl) {
    res.status(400).send("모든필드를 입력해주세요.");
  }
  models.Product.create({ description, price, seller, imageUrl, name })
    .then((result) => {
      console.log("상품 생성 결과 : ", result);
      res.send({
        result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("상품 업로드에 문제가 발생했습니다.");
    });
});
그랩님의 프로필 이미지
그랩
지식공유자

아 다행이에요~! 질문은 언제나 편하게 해주시면 됩니다! 

화이팅 💪💪💪

0

yami654님의 프로필 이미지
yami654
질문자

post '/products' 로직에 return을 붙여서 다시 해봤는데 아래같이 에러가 떠요.. 밑에 소스코드 return부분 맞게 썼는지좀 봐주세요.. !

그리고 return을 붙혔을 때 메인화면이랑 데이터베이스에 업로드 됐던것도 안돼요..

const express = require("express");
const cors = require("cors");
const app = express();
const models = require("./models");
const multer = require("multer");
const upload = multer({
  storage: multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, "uploads/");
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname);
    },
  }),
});
const port = 8080;

app.use(express.json());
app.use(cors());
app.use("/uploads", express.static("uploads"));

app.get("/products", (req, res) => {
  models.Product.findAll({
    order: [["createdAt", "DESC"]],
    attributes: ["id", "name", "price", "createdAt", "seller", "imageUrl"],
  })
    .then((result) => {
      console.log("PRODUCTS: ", result);
      res.send({
        products: result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("에러 발생");
    });
});

app.post("/products", (req, res) => {
  const body = req.body;
  const { name, description, price, seller, imageUrl } = body;
  if (!name || !description || !price || !seller || imageUrl) {
    return res.status(400).send("모든필드를 입력해주세요.");
  }
  models.Product.create({ description, price, seller, imageUrl, name })
    .then((result) => {
      console.log("상품 생성 결과 : ", result);
      return res.send({
        result,
      });
    })
    .catch((error) => {
      console.error(error);
      return res.status(400).send("상품 업로드에 문제가 발생했습니다.");
    });
});

app.get("/products/:id", (req, res) => {
  const params = req.params;
  const { id } = params;
  models.Product.findOne({
    where: {
      id: id,
    },
  })
    .then((result) => {
      console.log("PRODUCTS :", result);
      res.send({
        product: result,
      });
    })
    .catch((error) => {
      console.error(error);
      return res.status(400).send("상품 조회에 에러가 발생했습니다.");
    });
});

app.post("/image", upload.single("image"), (req, res) => {
  const file = req.file;
  console.log(file);
  res.send({
    imageUrl: file.path,
  });
});

app.listen(port, () => {
  console.log("그랩의 쇼핑몰 서버가 돌아가고 있습니다.");
  models.sequelize
    .sync()
    .then(() => {
      console.log("DB 연결 성공!");
    })
    .catch((error) => {
      console.error(err);
      console.log("DB 연결 에러");
      process.exit();
    });
});
그랩님의 프로필 이미지
그랩
지식공유자

넵 특정 컴퓨터 환경(일부 Windows)에서는 res 메소드가 호출되고도 아래 코드가 실행되서 생기는 이슈인 것 같습니다.

현재 클라이언 로그를 보면 status code가 400인 에러로, 작성해주신 서버 코드의 모든 내용을 입력하지 않았을 때 필터되는 코드가 동작한 것을 확인할 수 있습니다. 즉 현재 필드를 제대로 입력하지 않았다고 서버에서 응답해주는 구조입니다. 만약 입력 값을 채워서 요청을 보내면 DB에 값도 들어오고 정상적으로 화면 전환이 될 거에요~!

0

yami654님의 프로필 이미지
yami654
질문자

네 upload 소스코드입니다.!

import {
  Form,
  Divider,
  Input,
  InputNumber,
  Button,
  Upload,
  message,
} from "antd";
import "./index.css";
import { ForkOutlined } from "@ant-design/icons";
import { useState } from "react";
import { API_URL } from "../config/constants.js";
import axios from "axios";
import { useHistory } from "react-router-dom";

function UploadPage() {
  const [imageUrl, setImageUrl] = useState(null);
  const history = useHistory();
  const onSubmit = (values) => {
    axios
      .post(`${API_URL}/products`, {
        name: values.name,
        description: values.description,
        seller: values.seller,
        price: parseInt(values.price),
        imageUrl: imageUrl,
      })
      .then((result) => {
        console.log(result);
        history.replace("/");
      })
      .catch((error) => {
        console.error(error);
        message.error(`에러가 발생했습니다.${error.message}`);
      });
  };
  const onChangeImage = (info) => {
    if (info.file.status === "uploading"{
      return;
    }
    if (info.file.status === "done"{
      const response = info.file.response;
      const imageUrl = response.imageUrl;
      setImageUrl(imageUrl);
    }
  };
  return (
    <div id="upload-container">
      <Form name="상품 업로드" onFinish={onSubmit}>
        <Form.Item
          name="upload"
          label={<div className="upload-label">상품 사진</div>}
        >
          <Upload
            name="image"
            action={`${API_URL}/image`}
            listType="picture"
            showUploadList={false}
            onChange={onChangeImage}
          >
            {imageUrl ? (
              <img id="upload-img" src={`${API_URL}/${imageUrl}`} />
            ) : (
              <div id="upload-img-placeholder">
                <img src="/images/icons/camera.png" />
                <span>이미지를 업로드해주세요.</span>
              </div>
            )}
          </Upload>
        </Form.Item>
        <Divider />
        <Form.Item
          label={<div className="upload-label">판매자 명</div>}
          name="seller"
          rules={[{ required: true, message: "판매자 이름을 입력해주세요" }]}
        >
          <Input
            className="upload-name"
            size="large"
            placeholder="이름을 입력해주세요."
          />
        </Form.Item>
        <Divider />
        <Form.Item
          name="name"
          label={<div className="upload-label">상품 이름</div>}
          rules={[{ required: true, message: "상품 이름을 입력해주세요." }]}
        >
          <Input
            className="upload-name"
            size="large"
            placeholder="상품 정보를 입력해주세요."
          />
        </Form.Item>
        <Divider />
        <Form.Item
          name="price"
          label={<div className="upload-label">상품 가격</div>}
          rules={[{ required: true, message: "상품 가격을 입력해주세요" }]}
        >
          <InputNumber defaultValue={0} className="upload-price" size="large" />
        </Form.Item>
        <Divider />
        <Form.Item
          name="description"
          label={<div className="upload-label">상품 소개</div>}
          rules={[{ required: true, message: "상품 소개를 입력해주세요." }]}
        >
          <Input.TextArea
            size="large"
            id="product-description"
            showCount
            maxLength={300}
            placeholder="상품 소개를 적어주세요."
          />
        </Form.Item>
        <Form.Item>
          <Button id="submit-button" size="large" htmlType="submit">
            문제 등록하기
          </Button>
        </Form.Item>
      </Form>
    </div>
  );
}

export default UploadPage;
그랩님의 프로필 이미지
그랩
지식공유자

다시 확인해봤는데, 해당 에러는 res.json 혹은 res.send 같이 response를 주는 메소드가 중복으로 불렸을 때 인 것 같습니다!

post '/products' 로직에 res.send, res.json가 들어간 표현문에 전부 return을 붙여보시겠어요?

예: return res.status(404).send("모든 필드를 입력해주세요")

0

yami654님의 프로필 이미지
yami654
질문자

client 소스코드가 main - index.js 코드 맞나요??

import React from "react";
import "./index.css";
import axios from "axios";
import { Link } from "react-router-dom";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { API_URL } from "../config/constants.js";

dayjs.extend(relativeTime);

function MainPage() {
  const [products, setProducts] = React.useState([]);
  React.useEffect(function () {
    axios
      .get(`${API_URL}/products`)
      .then(function (result) {
        const products = result.data.products;
        setProducts(products);
      })
      .catch(function (error) {
        console.error("에러발생 : ", error);
      });
  }, []);

  return (
    <div>
      <div id="banner">
        <img src="images/banners/banner1.png" />
      </div>
      <h1 id="product-headline">판매되는 상품들</h1>
      <div id="product-list">
        {products.map(function (product, index) {
          return (
            <div className="product-card">
              <Link className="product-link" to={`/products/${product.id}`}>
                <div>
                  <img
                    className="product-img"
                    src={`${API_URL}/${product.imageUrl}`}
                  /> 
                </div>
                <div className="product-contents">
                  <span calssName="product-name">{product.name}</span>
                  <span calssName="product-price">{product.price}</span>
                  <div className="product-footer">
                    <div calssName="product-seller">
                      <img
                        className="product-avatar"
                        src="images/icons/avatar.png"
                      />
                      <span>{product.seller}</span>
                    </div>
                    <span calssName="product-date">
                      {dayjs(product.createdAt).fromNow()}
                    </span>
                  </div>
                </div>
              </Link>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default MainPage;
그랩님의 프로필 이미지
그랩
지식공유자

아 upload쪽 소스코드 부탁드립니다 :)

아마 upload 버튼이 눌렸을 때 불리는 함수 쪽에 문제가 있는 것 같아요

0

yami654님의 프로필 이미지
yami654
질문자

상품등록하면 브라우저랑 데이터베이스에 정상적으로 업로드는 됩니다. 

등록 후 에 자동으로 메인페이지로 돌아가는것만 안되고 있어요 ㅠ

그랩님의 프로필 이미지
그랩
지식공유자

client 쪽 소스코드를 보여주셔야 할 것 같아요~! client 업로드 코드 부분에서 문제가 있는 것 같아 보입니다~!

0

그랩님의 프로필 이미지
그랩
지식공유자

업로드를 눌렀을 때 실제로 데이터베이스에는 상품이 잘 들어가나요? 웹 브라우저에서 새로고침을 했을 때 정상적으로 업로드한 상품이 보이는지 궁금합니다!

yami654님의 프로필 이미지
yami654
질문자

상품등록하면 브라우저랑 데이터베이스에 정상적으로 업로드는 됩니다. 

등록 후 에 자동으로 메인페이지로 돌아가는것만 안되고 있어요 ㅠ

yami654님의 프로필 이미지
yami654

작성한 질문수

질문하기