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

Levi님의 프로필 이미지

작성한 질문수

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

포트폴리오 리뷰

댓글 비밀번호 입력 오류

해결된 질문

24.08.19 23:05 작성

·

75

0

안녕하세요, 댓글 삭제 기능을 구현하던 도중 Modal에서 입력받은 비밀번호가 제가 댓글을 생성할 때 입력했던 비밀번호와 동일함에도 비밀번호가 틀렸다는 에러 메시지가 나옵니다.

제가 작성한 코드에서 어떠한 오류가 있는 건지 가르쳐주시면 감사하겠습니다...

 

BoardComment Container

import { useState } from "react";
import { useRouter } from "next/router";
import { useMutation, useQuery } from "@apollo/client";
import BoardCommentsUI from "./BoardComments.presenter";
import {
  FETCH_BOARD,
  CREATE_BOARD_COMMENT,
  FETCH_BOARD_COMMENTS,
  DELETE_BOARD_COMMENT,
} from "./BoardComments.queries";
import { MouseEvent, ChangeEvent, MouseEventHandler } from "react";
import {
  IMutation,
  IMutationCreateBoardCommentArgs,
  IMutationDeleteBoardCommentArgs,
  IQuery,
  IQueryFetchBoardArgs,
  IQueryFetchBoardCommentsArgs,
} from "../../../../commons/types/generated/types";

export default function BoardComments() {
  const [writer, setWriter] = useState("");
  const [password, setPassword] = useState("");
  const [contents, setContents] = useState("");
  const [rating, setRating] = useState(0);
  const [user, setUser] = useState("");
  const [boardCommentId, setBoardCommentId] = useState("");
  const [modalPassword, setModalPassword] = useState("");
  const [contentLength, setContentLength] = useState(0);

  const [isOpen, setIsOpen] = useState(false);

  const router = useRouter();

  if (typeof router.query.boardId !== "string") {
    router.query.boardId = Array.isArray(router.query.boardId)
      ? router.query.boardId[0] 
      : String(router.query.boardId);
  }

  const { data } = useQuery<Pick<IQuery, "fetchBoard">, IQueryFetchBoardArgs>(
    FETCH_BOARD,
    {
      variables: {
        boardId: router.query.boardId,
      },
    }
  );

  const { data: commentData, refetch } = useQuery<
    Pick<IQuery, "fetchBoardComments">,
    IQueryFetchBoardCommentsArgs
  >(FETCH_BOARD_COMMENTS, {
    variables: {
      boardId: router.query.boardId,
    },
  });

  const [createBoardComment] = useMutation<
    Pick<IMutation, "createBoardComment">,
    IMutationCreateBoardCommentArgs
  >(CREATE_BOARD_COMMENT);

  const [deleteBoardComment] = useMutation<
    Pick<IMutation, "deleteBoardComment">,
    IMutationDeleteBoardCommentArgs
  >(DELETE_BOARD_COMMENT);

  const onChangeWriter = (event: ChangeEvent<HTMLInputElement>) => {
    setWriter(event.target.value);
  };

  const onChangePassword = (event: ChangeEvent<HTMLInputElement>) => {
    setPassword(event.target.value);
  };

  const onChangeContents = (event: ChangeEvent<HTMLTextAreaElement>) => {
    setContents(event.target.value);
    setContentLength(event.target.value.length);
  };

  const onChangeRating = (value: number) => {
    setRating(value);
  };

  const onChangeUser = (event: ChangeEvent<HTMLInputElement>) => {
    setUser(event.target.value);
  };

  const onChangeModalPassword = (event: ChangeEvent<HTMLInputElement>) => {
    setModalPassword(event.target.value);
  };

  const showModal = (event: MouseEvent<HTMLImageElement>): void => {
    setBoardCommentId(event.currentTarget.id);
    setIsOpen(true);
    console.log(boardCommentId);
  };

  const handelOk = (): void => {
    setIsOpen(false);
  };

  const handelCancel = (): void => {
    setIsOpen(false);
  };

  const onClickSubmitComment: MouseEventHandler<
    HTMLButtonElement
  > = async () => {
    try {
      if (typeof router.query.boardId !== "string") {
        return;
      }
      await createBoardComment({
        variables: {
          boardId: router.query.boardId,
          createBoardCommentInput: {
            writer,
            password,
            contents,
            rating,
          },
        },
      });
      refetch();
    } catch (error) {
      console.log(error.message);
    }
    setRating(0);
    setWriter("");
    setPassword("");
    setContents("");
  };

  const onClickDeleteComment = async (
    event: MouseEvent<HTMLButtonElement>
  ): Promise<void> => {
    try {
      await deleteBoardComment({
        variables: {
          boardCommentId,
          password: modalPassword,
        },
      });
      refetch();
    } catch (error) {
      alert(error.message);
    }
    setIsOpen(false);
    setModalPassword("");
  };

  return (
    <BoardCommentsUI
      data={data}
      commentData={commentData}
      writer={writer}
      password={password}
      contents={contents}
      modalPassword={modalPassword}
      contentLength={contentLength}
      rating={rating}
      user={user}
      isOpen={isOpen}
      onChangeWriter={onChangeWriter}
      onChangePassword={onChangePassword}
      onChangeRating={onChangeRating}
      onChangeContents={onChangeContents}
      onChangeUser={onChangeUser}
      onChangeModalPassword={onChangeModalPassword}
      onClickSubmitComment={onClickSubmitComment}
      onClickDeleteComment={onClickDeleteComment}
      showModal={showModal}
      handelOk={handelOk}
      handelCancel={handelCancel}
    />
  );
}

BoardComment Presenter

import * as S from "./BoardComments.styles";
import { IBoardCommentsUIProps } from "./BoardComments.types";
import { Rate } from "antd";

export default function BoardCommentsUI(props: IBoardCommentsUIProps) {
  return (
    <S.Container>
      <S.PasswordCheck
        open={props.isOpen}
        onOk={props.onClickDeleteComment}
        onCancel={props.handelCancel}
      >
        비밀번호 입력:{" "}
        <input type="text" onChange={props.onChangeModalPassword} />
      </S.PasswordCheck>

      <S.CommentTitleWrapper>
        <S.CommentIcon src="/icon/rate_review.png" />
        댓글
      </S.CommentTitleWrapper>
      <S.CommentInputWrapper>
        <S.CommentInputWrapperHeader>
          <S.CommentWriter
            type="text"
            placeholder="작성자"
            onChange={props.onChangeWriter}
            value={props.writer}
          />
          <S.CommentPassword
            type="password"
            placeholder="비밀번호"
            onChange={props.onChangePassword}
            value={props.password}
          />
          <Rate onChange={props.onChangeRating} value={props.rating} />
        </S.CommentInputWrapperHeader>

        <S.CommentInputWrapperBody>
          <S.CommentInputWrapperBottom
            placeholder="개인정보를 공유 및 요청하거나, 명예 훼손, 무단 광고, 불법 정보 유포시 모니터링 후 삭제될 수 있으며, 이에 대한 민형사상 책임은 게시자에게 있습니다."
            onChange={props.onChangeContents}
            maxLength={99}
            value={props.contents}
          />
          <S.CommentTextCount>{props.contentLength}/100</S.CommentTextCount>
          <S.CommentSubmitButton onClick={props.onClickSubmitComment}>
            등록하기
          </S.CommentSubmitButton>
        </S.CommentInputWrapperBody>
      </S.CommentInputWrapper>
      <S.CommentListWrapper>
        {props.commentData?.fetchBoardComments.map((el) => (
          <S.CommentListItemWrapper key={el._id}>
            <S.CommentListProfileWrapper>
              <S.CommentListProfileImage src="/icon/profile.png" />
            </S.CommentListProfileWrapper>
            <S.CommentListContentsWrapper>
              <S.CommentListContentsHeader>
                <S.CommentListWriter>{el.writer}</S.CommentListWriter>
                <Rate disabled defaultValue={el.rating} />
              </S.CommentListContentsHeader>
              <S.CommentListContents>{el.contents}</S.CommentListContents>
              <S.CommentListDate>2024-07-27</S.CommentListDate>
            </S.CommentListContentsWrapper>
            <S.CommentListItemButtonWrapper>
              <S.CommentListItemButton
                src="/icon/mode.png"
                //onClick={() => props.onClickDeleteComment(el._id)}
              />
              <S.CommentListItemButton
                src="/icon/clear.png"
                //onClick={() => props.onClickDeleteComment(el._id)}
                id={el._id}
                onClick={props.showModal}
              />
            </S.CommentListItemButtonWrapper>
          </S.CommentListItemWrapper>
        ))}
      </S.CommentListWrapper>
    </S.Container>
  );
}

 

답변 2

0

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

2024. 08. 22. 14:17

안녕하세요, 댓글을 등록할 때 입력한 password와 삭제 요청 직전 모달창에 입력한 패스워드를 모두 출력해보았는데, 같은 비밀번호를 입력했음에도 여전히 같은 오류가 나타납니다. ㅠㅠ

image.png
{
    "errors": [
        {
            "message": "비밀번호가 일치하지 않습니다.",
            "locations": [
                {
                    "line": 2,
                    "column": 3
                }
            ],
            "path": [
                "deleteBoardComment"
            ],
            "extensions": {
                "code": "INTERNAL_SERVER_ERROR",
                "exception": {
                    "stacktrace": [
                        "Error: 비밀번호가 일치하지 않습니다.",
                        "    at Object.callErrorProcessor (/codecamp_backend_api/dist/common/libraries/errorProcessor.js:8:11)",
                        "    at DeleteBoardCommentService.checkBoardCommentExistsAndPassword (/codecamp_backend_api/dist/api/boardComment/services/mutation/deleteBoardComment.service.js:37:36)",
                        "    at runMicrotasks (<anonymous>)",
                        "    at processTicksAndRejections (internal/process/task_queues.js:93:5)",
                        "    at async target (/codecamp_backend_api/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)",
                        "    at async /codecamp_backend_api/node_modules/@nestjs/core/helpers/external-proxy.js:9:24"
                    ]
                }
            }
        }
    ],
    "data": null
}

 

노원두님의 프로필 이미지
노원두
지식공유자

2024. 08. 24. 12:29

안녕하세요! Levi님!

현재 graphql 플레이그라운드에서 직접 게시글을 등록한 후, 댓글을 달고 삭제하는 과정까지 정상적으로 이루어진 것을 확인했어요!

 

따라서, 현재 코드상에 문제가 있는 것 같아요!
문제는 크게 댓글등록, 댓글삭제 2가지 부분으로 나눠서 확인해 주셔야 합니다!


1. 댓글 등록시에 비밀번호가 제대로 전송되었는지 확인이 필요해요!
=> 댓글 등록시 개발자도구 => 네트워크탭 => 페이로드 => variables 부분에 password가 전송되고 있는지 확인해 주세요!
(댓글 등록시에 비밀번호가 정상적으로 전송되었다면, 코드상이 아니라 플레이그라운드에서 직접 삭제도 가능하기 때문에, 플레이그라운드에서 해당 비밀번호로 삭제를 시도해 보셔서, 등록시의 문제였는지, 삭제시의 문제였는지 확인해 보세요!)

  1. 등록시 문제가 아니라면, 삭제 요청시 비밀번호가 제대로 전송되고 있는지 네트워크탭을 통한 확인이 필요해요!
    역시 마찬가지로 삭제 요청시, 개발자도구 => 네트워크탭 => 페이로드 => variables 부분에서 password가 입력한 password로 정상적으로 전송되고 있는지 확인이 필요할 것 같아요!

0

노원두님의 프로필 이미지
노원두
지식공유자

2024. 08. 21. 21:19

안녕하세요! Levi님!

전체적인 코드를 보았을 때, 오타 없이 잘 작성된 것 같아요!
따라서, 세부적인 부분에서 문제가 있는 것 같은데요!

 

이러한 경우에 아래와 같은 해결 방법으로 시도해 보세요!^^

  1. 네트워크 탭에서 요청된 비밀번호가 제대로 보내지고 있는지

  2. 요청하기 바로 직전. 즉, onClickDeleteComment 함수의 첫번째 줄에서 console.log가 제대로 찍히는지

  3. 만약, 찍히지 않는다면? 입력하는 함수에서 제대로 입력을 받아오는지 console.log 찍어보기

Levi님의 프로필 이미지

작성한 질문수

질문하기