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

akdlswjf2님의 프로필 이미지
akdlswjf2

작성한 질문수

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

로직이 떠오르지 않습니다...

작성

·

342

1

제가 이 강의를 통해서 웹 사이트를 제작하는 과정에 있습니다

지금 구현하고자 하는 페이지가 디비에 등록된 방 (방에 대한 정보 : 위치, 지정날짜, 인원 등등)을 고객이 방에 대한 정보에 대해 입력을 하고 입력한 방과 일치하는 방만을 화면에 뿌려주는 작업을 하고 있습니다. (야놀자에서 방을 예약할 때 자신이 이용하고자 하는 숙소의 위치나 체크인 체크아웃 날짜를 입력했을 때 해당 방만을 보여주는 페이지라고 생각하시면 됩니다!)

그런데 방 조회 로직에서 조금 어려움을 겪고 있습니다ㅠㅠㅠㅠ

axios 통신을 통해 .get 부분에 조건문을 달아주면 될 것 같은데 코딩 경험이 많지가 않아서 어떻게 로직을 구현해야 할지 조금 감이 안 잡힙니다 강사님에게 조언을 요청하고자 질문을 남겨봅니다!

답변 3

0

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

where 조건문을 서버쪽에서 사용합니다!!

현재 코드는 다음과 같습니다

서버쪽 코드는 전체 코드가 아닌 조회로직에 사용되는 코드들로 올려보았습니다!

문제점이 메인페이지에서 사용자의 입력값을 셀렉트하고 검색을 눌렀을 때,  해당 조건에 맞는 방이 출력되는 것이 아닌 디비에 있는 모든 방들이 출력이 됩니다.

F12버튼을 눌러 콘솔창을 확인해본 결과 디비에 있는 모든 방들이 찍히는 것이 지금의 문제점 같습니다.

 window.location.href = "/search";

하지만 해당 코드가 문제인건지 search 페이지에서 이 코드를 주석처리를 하고 사용자의 입력값을 셀렉하고 검색버튼을 눌렀을 땐 사용자가 입력한 내용들이 콘솔에 찍힙니다.

서버상에 찍히는 콘솔입니다.

Executing (default): SELECT `id`, `address1`, `address2`, `address3`, `address4`, `datein`, `dateout`, `roomtype`, `people`, `price`, `description`, `imageurl` FROM `Rooms` AS `Rooms` WHERE `Rooms`.`address1` = '인천' AND `Rooms`.`address2` = '미추홀구' AND `Rooms`.`datein` = '2021-04-25' AND `Rooms`.`dateout` = '2021-04-28' AND `Rooms`.`roomtype` = '2' AND `Rooms`.`people` = '2' ORDER BY `Rooms`.`createdAt` DESC;

{

  address1: '인천',

  address2: '미추홀구',

  datein: '2021-04-25',

  dateout: '2021-04-28',

  roomtype: '2',

  people: '2'

}

Rooms :  [

  {

    id: 17,

    address1: '인천',

    address2: '미추홀구',

    address3: '용현동',

    address4: '용현동 12-345',

    datein: '2021-04-25',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 50000,

    description: '야경이 멋진 방',

    imageurl: '/roomImages/s1.png'

  }

단, 이 코드를 주석으로 풀었을 때는 검색버튼을 누르는 동시에 콘솔에는 사용자가 입력한 값이 찍히지 않고 디비에 있는 모든 방들이 찍히고 화면에 출력됩니다.

메인페이지에서 사용자의 입력값을 셀렉하고 검색버튼을 눌렀을 때 해당 콘솔이 서버쪽에 찍힙니다.

서버에 찍힌 콘솔은 쿼리를 하나도 가져오지 못하는 것을 확인하였고 간단한 테스트를 진행해봤습니다.

location.href = "/search?addr1=" + values.addr1 + "&addr2=" + values.addr2;

이렇게 하였을 때 값을 제대로 전달해주지 않았더라면 addr1=undefined이 찍혀야지 맞지만

유저가 입력한 값 그대로 URL에 송출이 됩니다.

하지만 서버 콘솔에는 유저가 입력한 값은 하나도 나오지 않습니다.

{}

Executing (default): SELECT `id`, `address1`, `address2`, `address3`, `address4`, `datein`, `dateout`, `roomtype`, `people`, `price`, `description`, `imageurl` FROM `Rooms` AS `Rooms` ORDER BY `Rooms`.`createdAt` DESC;

Rooms :  [

  {

    id: 30,

    address1: '인천',

    address2: '미추홀구',

    address3: '용현동',

    address4: '백호오피스텔',

    datein: '2021-04-12',

    dateout: '2021-04-13',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '문화의 거리 7분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s9.png'

  },

  {

    id: 25,

    address1: '인천',

    address2: '부평구',

    address3: '용현동',

    address4: 'State오피스텔',

    datein: '2021-04-27',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '문화의 거리 8분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s8.png'

  },

  {

    id: 24,

    address1: '인천',

    address2: '동구',

    address3: '용현동',

    address4: '베스트오피스텔',

    datein: '2021-04-27',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '문화의 거리 5분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s7.png'

  },

  {

    id: 23,

    address1: '인천',

    address2: '연수구',

    address3: '용현동',

    address4: '케이오피스텔',

    datein: '2021-04-29',

    dateout: '2021-04-30',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '문화의 거리  3분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s6.png'

  },

  {

    id: 22,

    address1: '인천',

    address2: '서구',

    address3: '용현동',

    address4: '제이오피스텔',

    datein: '2021-04-28',

    dateout: '2021-04-29',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '인하대역 2번 출구 10분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s5.png'

  },

  {

    id: 21,

    address1: '인천',

    address2: '부평구',

    address3: '용현동',

    address4: '마로오피스텔',

    datein: '2021-04-27',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '인하대역 2번 출구 15분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s4.png'

  },

  {

    id: 20,

    address1: '인천',

    address2: '중구',

    address3: '용현동',

    address4: '헬마빌오피스텔',

    datein: '2021-04-27',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 80000,

    description: '논현역 2번 출구 3분거리 최적의 오피스텔입니다.',

    imageurl: '/roomImages/s3.png'

  },

  {

    id: 19,

    address1: '인천',

    address2: '남동구',

    address3: '문학동',

    address4: '문학동 77-777',

    datein: '2021-04-26',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 30000,

    description: 'ㅇㅁㄴㅇㅁㄴ',

    imageurl: '/roomImages/s2.png'

  },

  {

    id: 17,

    address1: '인천',

    address2: '미추홀구',

    address3: '용현동',

    address4: '용현동 12-345',

    datein: '2021-04-25',

    dateout: '2021-04-28',

    roomtype: '2',

    people: '2',

    price: 50000,

    description: '야경이 멋진 방',

    imageurl: '/roomImages/s1.png'

  }

<서버>

const express = require("express");
const cors = require("cors");
const app = express();
const models = require("./models");
const port = 8090;
const multer = require("multer");
const addroom = multer({
  storage: multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, "addroom/"); // 이미지 저장 경로
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname); // 이미지 파일 이름 설정
    },
  }),
});
app.use(express.json());
app.use(cors());
app.use("/addroom", express.static("addroom"));

app.get("/search", (req, res) => {
  console.log(req.body);
  //console.log(req.query);

  // 사용자의 입력을 바탕으로 검색 기능 필터 로직
  const whereOption = {};
  if (req.query.address1 && typeof req.query.address1 === "string"{
    whereOption["address1"= req.query.address1;
  }
  if (req.query.address2 && typeof req.query.address2 === "string"{
    whereOption["address2"= req.query.address2;
  }
  if (req.query.datein && typeof req.query.datein === "string"{
    whereOption["datein"= req.query.datein;
  }
  if (req.query.dateout && typeof req.query.dateout === "string"{
    whereOption["dateout"= req.query.dateout;
  }
  if (req.query.roomtype && typeof req.query.roomtype === "string"{
    whereOption["roomtype"= req.query.roomtype;
  }
  if (req.query.people && typeof req.query.people === "string"{
    whereOption["people"= req.query.people;
  }

  models.Rooms.findAll({
    order: [["createdAt", "DESC"]], // 방 조회 정렬 (오름차순) 로직 -> 최근에 등록한 방이 먼저 보이게끔 설정하기 위해서

    attributes: [
      "id",
      "address1",
      "address2",
      "address3",
      "address4",
      "datein",
      "dateout",
      "roomtype",
      "people",
      "price",
      "description",
      "imageurl",
    ], // 가져오고 싶은 데이터만 받아올 수 있는 로직
    where: {
      ...whereOption,
    },
    raw: true,
  })
    .then((result) => {
      console.log("Rooms : ", result);
      res.send({
        Rooms: result,
      });
    })
    .catch((error) => {
      console.error(error);
      res.status(400).send("에러 발생");
    });
});
app.listen(port, () => {
  console.log("airtrace 서버가 돌아가고 있습니다");
  models.sequelize
    .sync()
    .then(() => {
      console.log("DB 연결 성공!");
    })
    .catch((err) => {
      console.error(err);
      console.log("DB 연결 에러");
      process.exit();
    });
});

<메인 페이지 프론트>

import "./index.css";
import { Link } from "react-router-dom";
import { Button, Form } from "antd";
import { API_URL } from "../config/constants";
import axios from "axios";

function MainPage() {
  const onSubmit = (values) => {
    console.log(values);
    axios
      .post(`${API_URL}/search`, {
        //서버통신
        params: {
          address1: values.addr1,
          address2: values.addr2,
          datein: values.datein,
          dateout: values.dateout,
          roomtype: values.roomtype,
          people: values.people,
          price: values.price,
          imageurl: values.imageurl,
        },
      })
      .then((result) => {
        console.log(result);
      })
      .catch(function (error) {
        console.error(error);
      });

   location.href =
      "/search";
   
  };
  return (
    <>
      <div>
        <div id="header">
          <div id="logo">
            <Link to="/">
              <img src="../images/logo.png" id="logo" alt="logo" />
            </Link>
          </div>
          <Form
            className="formcss"
            name="방검색"
            
            onFinish={onSubmit}
          >
            <div id="searchbox">
              <div>
                <h4>도시선택</h4>
                <Form.Item name="addr1">
                  <select className="searchboxselect1">
                    <option></option>
                    <option value="서울">서울</option>
                    <option value="인천">인천</option>
                    <option value="경기">경기</option>
                    <option value="강원">강원</option>
                    <option value="대전">대전</option>
                    <option value="대구">대구</option>
                    <option value="충청">충청</option>
                    <option value="전라">전라</option>
                    <option value="경상">경상</option>
                    <option value="제주">제주</option>
                  </select>
                </Form.Item>
              </div>
              <div>
                <h4>구선택</h4>
                <Form.Item name="addr2">
                  <select className="searchboxselect2">
                    <option></option>
                    <option value="남동구">남동구</option>
                    <option value="미추홀구">미추홀구</option>
                    <option value="부평구">부평구</option>
                    <option value="중구">중구</option>
                    <option value="서구">서구</option>
                    <option value="동구">동구</option>
                    <option value="연수구">연수구</option>
                  </select>
                </Form.Item>
              </div>
              <div>
                <h4>체크인 날짜</h4>
                <Form.Item name="checkIn">
                  <input className="searchboxcheckin" type="date" />
                </Form.Item>
              </div>
              <div>
                <h4>체크아웃 날짜</h4>
                <Form.Item name="checkOut">
                  <input className="searchboxcheckout" type="date" />
                </Form.Item>
              </div>
              <div>
                <h4>방 타입</h4>
                <Form.Item name="roomtype">
                  <select className="searchboxroomtype">
                    <option>방타입</option>
                    <option value="1">1룸</option>
                    <option value="2">2룸</option>
                    <option value="3">3룸</option>
                  </select>
                </Form.Item>
              </div>
              <div>
                <h4>방 인원</h4>
                <Form.Item name="people">
                  <select className="searchboxpeople">
                    <option>인원</option>
                    <option value="1">1명</option>
                    <option value="2">2명</option>
                    <option value="3">3명</option>
                  </select>
                </Form.Item>
              </div>
            </div>
            <div id="searchclick">
              <Form.Item>
                <Button id="searchbutton" size="large" htmlType="submit">
                  검색
                </Button>
              </Form.Item>
            </div>
          </Form>
          <div className="joinbutton">
            <Link to="/login">
              <input type="button" id="login" value="로그인" />
            </Link>
            <Link to="/members">
              <input type="button" id="signup" value="회원가입" />
            </Link>
          </div>
        </div>
        <div id="main">
          <div id="maindescription">
            <img id="mainimg" src="../images/main2.jpg" />
            <div id="maincaption">
              <h1 className="mainh1">도시별 바로가기</h1>
            </div>
            <div id="mainboxtop">
              <div id="seoul">
                <button>서울</button>
              </div>
              <div id="incheon">
                <button>인천</button>
              </div>
              <div id="gyunggi">
                <button>경기</button>
              </div>
              <div id="gangwon">
                <button>강원</button>
              </div>
            </div>
            <div id="mainboxbottom">
              <div id="chungchung">
                <button>충청</button>
              </div>
              <div id="junra">
                <button>전라</button>
              </div>
              <div id="gyungsang">
                <button>경상</button>
              </div>
              <div id="jeju">
                <button>제주</button>
              </div>
            </div>
            <div id="mainbottomimg"></div>
          </div>
        </div>
      </div>
    </>
  );
}

export default MainPage;

<search 페이지 프론트>

import "./index.css";
import { Link } from "react-router-dom";
import { Button, Form } from "antd";
import { API_URL } from "../config/constants";
import axios from "axios";
import React from "react";
import ReactDOM from "react-dom";
import { useState, useEffect } from "react";

function searchPage() {
  const [rooms, setRooms] = useState([]);

  useEffect(function () {
    axios
      .get(`${API_URL}/search`)
      .then(function (result) {
        setRooms(
          result.data.Rooms.map((data) => {
            return data;
          })
        );
      })
      .catch(function (error) {
        console.error("에러 발생 : ", error);
      });
  }, []);

  const onSubmit = (values) => {
    //console.log("hi!");
    console.log(values);

    axios
      .get(`${API_URL}/`, {
        params: {
          address1: values.addr1,
          address2: values.addr2,
          datein: values.datein,
          dateout: values.dateout,
          roomtype: values.roomtype,
          people: values.people,
          price: values.price,
          imageurl: values.imageurl,
        },
        //서버통신
      })
      .then((result) => {
        console.log(result);
      })
      .catch(function (error) {
        console.error(error);
      });
    // window.location.href =
    //   "/search?addr1=" + values.addr1 + "&addr2=" + values.addr2;
  };

  return (
    <div>
      <div id="header">
        <div id="logo">
          <Link to="/">
            <img src="../images/logo.png" id="logo" alt="logo" />
          </Link>
        </div>
        <Form className="formcss" name="방검색" onFinish={onSubmit}>
          <div id="searchbox">
            <div>
              <h4>도시선택</h4>
              <Form.Item name="addr1">
                <select className="searchboxselect1">
                  <option></option>
                  <option value="서울">서울</option>
                  <option value="인천">인천</option>
                  <option value="경기">경기</option>
                  <option value="강원">강원</option>
                  <option value="대전">대전</option>
                  <option value="대구">대구</option>
                  <option value="충청">충청</option>
                  <option value="전라">전라</option>
                  <option value="경상">경상</option>
                  <option value="제주">제주</option>
                </select>
              </Form.Item>
            </div>
            <div>
              <h4>구선택</h4>
              <Form.Item name="addr2">
                <select className="searchboxselect2">
                  <option></option>
                  <option value="남동구">남동구</option>
                  <option value="미추홀구">미추홀구</option>
                  <option value="부평구">부평구</option>
                  <option value="중구">중구</option>
                  <option value="서구">서구</option>
                  <option value="동구">동구</option>
                  <option value="연수구">연수구</option>
                </select>
              </Form.Item>
            </div>
            <div>
              <h4>체크인 날짜</h4>
              <Form.Item name="datein">
                <input className="searchboxcheckin" type="date" />
              </Form.Item>
            </div>
            <div>
              <h4>체크아웃 날짜</h4>
              <Form.Item name="dateout">
                <input className="searchboxcheckout" type="date" />
              </Form.Item>
            </div>
            <div>
              <h4>방 타입</h4>
              <Form.Item name="roomtype">
                <select className="searchboxroomtype">
                  <option>방타입</option>
                  <option value="1">1룸</option>
                  <option value="2">2룸</option>
                  <option value="3">3룸</option>
                </select>
              </Form.Item>
            </div>
            <div>
              <h4>방 인원</h4>
              <Form.Item name="people">
                <select className="searchboxpeople">
                  <option>인원</option>
                  <option value="1">1명</option>
                  <option value="2">2명</option>
                  <option value="3">3명</option>
                </select>
              </Form.Item>
            </div>
          </div>
          <div id="searchclick">
            <Form.Item>
              <Button id="searchbutton" size="large" htmlType="submit">
                검색
              </Button>
            </Form.Item>
          </div>
        </Form>
        <div className="joinbutton">
          <Link to="/hostroom">
            <input type="button" id="login" value="방관리" />
          </Link>
          <Link to="/cusroom">
            <input type="button" id="signup" value="예약관리" />
          </Link>
        </div>
      </div>
      <div className="roomListBox">
        {rooms.map((room, index) => {
          console.log(room);
          return (
            <div className="roomBox" key={index}>
              <Link className="room-link" to={`/reservation/${room.id}`}>
                <img className="roomBoxImg" src={room.imageurl/>
                <div className="roomInfo">
                  <strong>
                    주소 : {room.address1} {room.address2} {room.address3}
                  </strong>
                  <p>가격 : {room.price}원 (1박)</p>
                  <p>기준 인원 : {room.people}</p>
                </div>
              </Link>
            </div>
          );
        })}
      </div>
    </div>
  );
}

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

현재 location.href 구문을 axios.get ... .then 안에다 적어보시겠어요?
axios.get은 일반적으로 비동기처리이기 때문에 통신 결과를 받아서 then에서 처리하기 전에 아래 코드인 location.href가 실행됩니다. 따라서 원하시는 동작이 데이터를 받은 후 location.href 동작을 원하신다면 then 안에 코드를 옮겨보세요~!

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

아 감사합니다ㅠㅠ

0

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

그러면 조건값은 항상 달라지니

이런 식으로 처리를 해주면 된다는 말씀이신가요?

그리고 서버에서는 이 쿼리 스트링의 값을 어떤 식으로 처리하게 되나요?

axios.get('https://apiserver.com', {
  params: {
    number: 유저의 입력값
    date : 유저의 입력값
   }
})
그랩님의 프로필 이미지
그랩
지식공유자

오 적어주신 코드처럼 작성을 하면 실제 요청에는 정상적으로 query가 url뒤에 붙어서 통신을 하게 될 거에요!

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

제가 조금 다른 로직을 연구해서 쿼리스트링이 아닌 where 조건문만을 이용해서 로직을 수행하고 있는데 F12를 눌러 관리자 모드로 보면 콘솔창에 사용자의 입력값에 따른 방만이 출력이 되고 있습니다 하지만 화면에 출력은 디비에 모든 방들이 출력이 되고 있습니다. 혹시 소스코드 올려봐도 괜찮을까요?

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

where조건문을 클라이언트(웹)에서 사용한다는 말씀이신가요?

서버쪽과 프론트쪽을 올려주시면 내일 다시 확인해보겠습니다 ㅎㅎ

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

넵ㅎㅎㅎ 항상 친절히 답변해주셔서 감사합니다!

0

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

재밌는 프로젝트를 하고 계시는군요.

고객이 정보들을 입력한다면 해당 정보들을 api 서버로 보내야 합니다. 정보를 얻기 위해 http 요청을 하는 경우 보통 GET method를 사용합니다(axios.get으로 구현 가능) 그리고 GET의 경우 정보를 표현할 때 querystring으로 구현이 가능합니다.

예시 : 인원수가 2명, 지정날짜 4월 27일일때 아래와 같이 querystring을 활용할 수 있겠죠? 

http://apiserver.com?number=2&date=2021-04-27 

이를 구현하기 위해선 아래와 같이 코드를 작성할 수 있을 거예요!

axios.get('https://apiserver.com', {
  params: {
    number: 2,
date : '2021-04-27'
  } })

이렇게 서버에 요청을 보낸 후 express 서버에서는 보낸 query string을 처리해서 데이터베이스에 요청을 하는 방식으로 구현이 될 거예요!

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

전체적인 흐름을 먼저 파악하시고 코딩으로 천천히 구현해보시는 것을 추천드립니다 :)

궁금한 부분들이 있으면 또 질문 주세요!

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

답변 감사합니다! 이걸 이제야 확인했네요ㅠㅠㅠㅠㅠㅠㅠㅠㅠ 한 번 시도하도록 하겠습니다

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

아 그리고 하나 생각이 들었습니다! where 조건문을 통해서 유저가 입력한 정보값과 일치한 방만 화면에 출력해주는 방법도 가능하지 않을까라는 생각이 들었는데 강사님은 어떻게 생각하시나요?

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

말씀하신 방법으로 보통 진행을 하게 됩니다.

클라이언트가 해당 url로 요청을 보내면 서버엣는 querystring에 들어간 number나 date를 추출한 후 where 조건문으로 데이터베이스에 쿼리를 하게 됩니다. 그리고 받은 방들을 다시 클라이언트에게 돌려주게 됩니다. 마지막으로 클라이언트는 받은 방 데이터들을 읽어서 화면에 그려주게 되는거죠!

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

답변 감사합니다 ㅎㅎ

akdlswjf2님의 프로필 이미지
akdlswjf2

작성한 질문수

질문하기