본문 바로가기
> 코딩애플 (부분공개)/Next.js로 웹서비스 만들기

삭제 기능 만들기 2 (Ajax 추가 내용과 에러 처리) 0:47

by 자몽주스 2024. 11. 11.
728x90

삭제기능 만들어오라던 숙제를 같이 해보도록 합시다.

나중에 혼자 코드짤 때도 제 코드 따라칠 것입니까 

잘 안되어도 혼자 이것저것 뭐라도 해보는 과정에서 실력이 늡니다. 

코드 따라치는건 학습이 아니고 타이핑 실력만 향상됩니다.

기능부터 한글로 설명해보면 

1. 삭제버튼 누르면 서버로 삭제요청 보냄 (URL, method도 정하기)

2. 근데 어떤 게시물 삭제할지 게시물 _id도 보내야 삭제를 정확히 잘해줄듯요 

3. 서버는 요청 들어오면 DB에서 그 게시물 삭제해줌 

이러면 될 것 같으니 이거 그대로 코드로 옮겨봅시다. 


1. 삭제버튼누르면 서버로 삭제요청보냄 

ajax 이용해서 

삭제버튼을 누르면

저 URL (/api/post/delete) 로

DELETE 메소드로 요청을 보냄. 

이제 저 경로로 요청하면 

서버 기능을 실행하고 싶으니까

서버 파일도 생성해줌. 

이렇게 되면 누군가가

저 경로로  (/api/post/delete)  요청을 하게 되면

저 안에 있는 코드를 실행해줄 것.

코드 안에 컴포넌트로 내용 채워줌. 

 

= 누가 여기로 요청을 하면 

DB 에 있던 글을 삭제하라고 코드를 짜보자. 

ㅁㄴㅇㄹㅁㄴㄹㅇㅇㅁㄹㅇ

 

**********************************0:47

일단 if 문 같은거 쓰면 좋을 것 같음. 

그리고 어떤 사람이

요청.method 를 DELETE 로 보냈다고 가정

그렇게 되면 중괄호 안의 코드 실행해달라고 짬.

만약 삭제를 하고 싶으면 저런 식으로

중괄호를 채워주면 될 것 같다. 

deleteOne 이라는 함수 사용

deleteOne 소괄호 안에는

삭제할 게시물의 정보를 집어 넣어주면 됨. 

 

그렇게 되면 저 정보를 갖고있는 

게시물 하나 찾아서 삭제해 줄 것.

보통 그래서 삭제할 게시물의 아이디를 집어넣는 경우가 많음.

그리고 삭제가 완료됐으면 응답도 해줘야함. 

그리고 요청이나 응답을 갖다 쓰고 싶으면

파라미터 추가해줘야함. 

우선 이 정도로 코드를 짰으면 

id 가 123인 게시물을 삭제해주는 것. 

어떤 id 가진 게시물 삭제해줘야할까? 

??? 자리 채워주려면 해야할 것. 

 

유저에게 보내라고 해보자. 

저기다가 body 라고 갖다 쓸 경우 

저기다가 뭔가를 집어넣어서 서버로 보낼 수 있음.

 


fetch('/api/post/delete', {method : 'DELETE'})

삭제버튼누르면 위 코드 실행하라고 코드짜놨는데 

 


2. 삭제할 게시물 _id도 서버로 보내면 좋을듯

게시물의 아이디를 보내보도록 하자.

= result[i]._id

delete 요청할때마다 body 란에 

현재 게시물의 아이디가 서버로 전송될 것. 

테스트 해보기 위해서 코드 주석처리

요청.body 를 출력해보기 

= 진짜로 유저가 저 아이디를 잘 보내고 있는 지 테스트

터미널 통해서 아이디가 잘 전송되는거 확인. 

 

참고사항) 

서버로 데이터를 보낼 때, 

문자나 숫자 자료는 대충 저런 식으로 보내도 잘 간다. 

근데 object 자료 같은

자료형을 보낼 때는

JSON.stringfy() 안에 집어넣어서 보내면 좋음. 

 

저 데이터를 출력해보면

JSON 화가 된 자료를 출력받을 수 있다. 

확인해보기. 

 

오브젝트가 저런식으로 돼있다.

따옴표가 쳐져있는거 확인.

= JSON 

오브젝트에다가 따옴표 다 친 것. 

 

따옴표를 쳐서 문자취급을 해줌.

= 서버랑 자유롭게 데이터를 주고받을 수 있다. 

안에 있는 1을 출력하고 싶으면 이런 식으로 하면 될 것 가튼데 안된다.

= JSON 임

= object 에서 데이터 출력하는 문법을 못쓴다.

JSON 안에 있던 1 같은 자료를 꺼내고 싶으면 

저런식으로 . 을 찍기 전에, 

JSON.parse 안에다가 집어넣으면 된다 .

그러면 따옴표 쳤던게 저런 식으로

따옴표가 없어질 것. 

이제 1 을 출력해볼 수 있다. 

body 안에다가 

이제 게시글의 아이디를 보내주기 

참고사항) 

DELETE 요청을 사용하는 경우엔, 

서버에서 저 데이터가 

수신이 잘 안되는 경우가 있음.

그럴 땐 그냥 POST 라고 작성해줘도 됨. 

= POST 요청으로 해도 전혀 상관이 없다 .

이제 요청.body 도 옮겨줌.

근데 DB 에 저장된 document 는 

저런 형식으로 돼있다

그래서 objectId 함수를 사용해서 집어넣어주면 될 것 같음. 

new 도 붙여줘야 함. 

 

정말 삭제가 되는지 확인해보기. 

 

근데 삭제가 가끔 안되는 경우도 있다. 

그럴 땐 저걸(result) 한 번 출력해보기.

= 몇 개의 게시물이 삭제됐는 지 출력해줌. 

삭제해보면

터미널에 result 가 출력되는거 확인가능. 

 

터미널 보게 디면 deletedCount 라는 속성 확인. 

1개의 게시물을 삭제했다는 의미 .

 

만약 삭제가 잘 안됐을 경우 저 부분이 0 이 뜸.

= if문으로 result 변수를 검사해보기.

= 그리고 거기에 맞게 응답.

deletedCount 가 0 이면 500을 보내달라는 응답 같은 것.

1 이면 200 보내달라는 응답. 

DB가 죽거나 없을 때

에러 처리 하고 싶으면

try/catch 사용

 

이거 사용하면 에러체크를 쉽게 할 수 있음.

= 우선 간단히 이정도 해둠. 


fetch('/api/post/delete', {method : 'DELETE', body : result[i]._id})

어떤 글을 삭제할지 정보를 안보내면 서버가 무슨 게시물을 삭제해야할지 모를테니까

삭제할 글의 _id도 보내봤습니다. 

 


3. 서버는 요청 들어오면 DB에서 그 게시물 삭제해줌 

 

/api/post/delete 경로로 DELETE 요청이 들어오면 게시물삭제해주는 API를 만들어봅시다. 

import { connectDB } from "@/util/database"
import { ObjectId } from "mongodb";

export default async function handler(요청, 응답) {
  if (요청.method == 'DELETE'){
    let db = (await connectDB).db('forum')
    let result = await db.collection('post').deleteOne({_id : new ObjectId(요청.body)});
    console.log(result)
    응답.status(200).json('삭제완료')
  }
}

- deleteOne() 안에 document 정보를 넣으면 그걸 찾아서 삭제해줍니다. 

- 유저가 전송한 데이터는 요청.body에 들어있습니다. 

 

이러면 기능 완성인거 같은데 삭제버튼 누르면 삭제 잘 되나 테스트해봅시다. 

뭔가 이상하게 안되는 부분이 있다면 에러메세지를 찾아보거나 

의심스러운 부분에서 변수같은 것들을 출력부터해보면 답을 알 수 있습니다. 


예외처리

 

데이터베이스같은 친구들은 항상 믿음직하지 않습니다. 

가끔 처리를 실패하는 경우도 있는데 그럴 경우 대처하는 코드도 짜놓는게 좋습니다. 

import { connectDB } from "@/util/database"
import { ObjectId } from "mongodb";

export default async function handler(요청, 응답) {
  if (요청.method == 'DELETE'){
    try {
      let db = (await connectDB).db('forum') 
      let result = await db.collection('post').deleteOne({_id : new ObjectId(요청.body._id)});
    } 
    catch (error) {
      응답.status(500)
    }
    
    만약에 result 결과가 이상하면 응답.status(500)
    result 결과가 정상이면 응답.status(200)
  }
}

- try, catch 문법을 쓰면 try 안에 있는 코드에서 이상한 에러가 날 경우 catch 안에 있는 코드를 대신 실행해줍니다.

- 수정, 삭제, 삽입 결과는 result 출력해보면 알 수 있기 때문에 그거 검사해보고

이상하면 그에맞는 응답을 해주면 좋습니다. 

- 참고로 삭제못한거랑 에러는 다른 것임 


Ajax 기능을 더 알아보자

Ajax 요청을 하고 나서,

특정 코드를 실행하고 싶은 경우

= 유저한테 삭제했다고 알림 주기 

저기다가 then 갖다 붙이기 

이렇게 써주면

삭제가 완료 됐을 때

( 서버에서 응답을 해 줬을 때 ) 

저기 안에 있는 코드를 실행해줌.

이렇게 써주면 

삭제가 완료 됐을 때

특정 코드를 실행해줌. 

또는 특정코드만 실행시켜주는 거 뿐만 아니라 

서버가 보낸 메시지나 데이터 같은 것도 출력해볼 수 있음. 

 

저렇게 응답 코드를 짰을 경우,

(데이터나 메시지 같은 걸 보내라고 코드를 짰을 경우) 

 

그 내용을 여기서도 출력해볼 수 있음. 

지금 보면 문자를 보내고 있음.

저걸 한 번 출력해보고 싶으면

then 안에다가 저렇게 코드를 짜면 될 것 같다.

then 이라는 함수를 한 번 더 써줌. 

r 출력해보기. 

글 삭제해서 콘솔창 확인해보기.

삭제완료라고

서버에서 보낸 메시지가 뜨는 거 확인할 수 있다.

ajax 요청을 하다가 

Error 생겼을 경우 처리하는 방법 알아보기. 

 

ajax 요청을 하다가 실패하는 경우 있음. 

실패하는 경우에 어떤 식으로 체크를 할까? 

우선 저 코드 복붙 

에러 상황은 2가지 정도가 존재

1) 서버가 에러 코드 전송했을 때 

= 서버에서 뭔가 에러가 나서 에러 코드를 전송했을 때.

2) 인터넷이 끊겼을때

저 부분에다가 코드 짜면 됨. 

첫번째 부분인 경우

= 서버가 에러코드를 전송했을 때 

저 빛나는 부분에다가 코드를 작성해주면 된다. 

그리고 ajax 가 성공적으로 완료됐을 때

특정 코드를 실행해주고 싶은 경우, 

저따가 써주면 됨

(성공시 실행할 코드)

fetch 라는 문법은 기본적으로

코드가 길고 복잡. 

= axios 쓰면 코드 좀 짧아짐. 

 

fetch 는 복붙해서 갖다 쓰자 

 

간단히 설명하기 위해 이정도로만 써줌.


fetch('/URL')
.then((r)=>r.json())
.then((result)=>{ console.log(result) })

서버에서 보낸 결과가 object, array 자료면 이렇게 출력해야합니다. 

fetch('/URL')
.then((r)=>{
  if(r.status == 200) {
    return r.json()
  } else {
    //서버가 에러코드전송시 실행할코드
  }
})
.then((result)=>{ 
  //성공시 실행할코드
}).catch((error)=>{
  //인터넷문제 등으로 실패시 실행할코드
  console.log(error)
})

특정 에러상황이 발생시 대처하고 싶으면 이렇게 코드짜놓으면 됩니다. 

이런건 복붙해서 씁시다. 

 

fetch 코드가 길고 귀찮아서 편리하게 바꿔주는 axios같은 라이브러리 설치해서 쓰는 사람들이 많습니다.

근데 Nextjs 13부터는 fetch가 특별한 기능이 추가되어있기 때문에

server component 함수 안에서 fetch() 쓸 일이 있을 경우 그거 그대로 쓰는게 좋습니다. 

지금의 client component 에선 라이브러리 설치하든 뭐하든 편한거 아무거나 대충 써도 됩니다. 

 

다음 시간엔 애니메이션이나 만들어봅시다.

728x90