SeoMiYoung / CA_nodedotjs_mongodb

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

list에서 특정 글의 상세페이지로 이동하기 - URL 파라미터 문법

SeoMiYoung opened this issue · comments

🔶 URL 파라미터 문법

URL파라미터 문법을 사용하면, 비슷한 /URL을 가진 API를 여러개 만들 필요가 없습니다.

예를 들어서,
/detail/1
/detail/2
/detail/3
/detail/4
만들고 싶으면, 일일히 각각

app.get('detail/1', () => {
    // detail1.ejs 보내주셈
})

app.get을 여러개 넣을 순 없잖아?
그래서 URL 파라미터 문법을 사용하는거야.

🔶 과정

🔸 (1) /detail/어쩌구 접속시 _id가 어쩌구인 게시물 찾기

특정 id에 대한 상세페이지를 만들고 싶은거야

[server.js]

const { ObjectId } = require('mongodb')

app.get('/detail/:id', async(요청, 응답) => {
    // collection에 있는 조건에 맞는 가장 첫번째 document만 가져와주세요.
    let result = await db.collection('shopData').findOne({ _id : new ObjectId(요청.params.id)})
    console.log(result)
    응답.render('detail.ejs', {result: result})
})

[detail.ejs]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="/css/main.css" rel="stylesheet"/>
</head>
<body class="grey-bg">
    <%- include('nav.ejs') %>
    <div class="detail-bg">
        <h4><%= result.title %></h4>
        <p><%= result.content %></p>
    </div> 
</body>
</html>

image

image

🔸 (2) list페이지에 이동 링크 만들기

현재 list페이지는 다음과 같다.
image

해당 페이지에서 특정 게시물을 누르면, 그 게시물에 대한 detail페이지를 보여주면 좋겠다.

[원래 list페이지]

<body class="grey-bg">
    <%- include('nav.ejs') %>
    <div class="white-bg">
        <% for (let i=0; i<글목록.length; i++) { %>
            <div class="list-box">
                <h4><%= 글목록[i].title %></h4>
                <p><%= 글목록[i].content %></p>
            </div>
        <% } %>
    </div> 
</body>

[링크를 걸고 난 뒤, list페이지]

<body class="grey-bg">
    <%- include('nav.ejs') %>
    <div class="white-bg">
        <% for (let i=0; i<글목록.length; i++) { %>
            <div class="list-box">
                <h4><a href="/detail/<%= 글목록[i]._id %>">링크</a><%= 글목록[i].title %></h4>
                <p><%= 글목록[i].content %></p>
            </div>
        <% } %>
    </div> 
</body>

Animation

조금 더 보완해서, 제목을 클릭하면 상세페이지로 넘어가게 구현하기

<body class="grey-bg">
    <%- include('nav.ejs') %>
    <div class="white-bg">
        <% for (let i=0; i<글목록.length; i++) { %>
            <div class="list-box">
                <h4><a href="/detail/<%= 글목록[i]._id %>"><%= 글목록[i].title %></a></h4>
                <p><%= 글목록[i].content %></p>
            </div>
        <% } %>
    </div> 
</body>

image

🔶 예외처리

만약에 user가 이상한 링크를 입력했다면?
http://localhost:8080/detail/66756f56da39c4c710406364가 아니라,
http://localhost:8080/detail/66756f56da39c4c71040636411111111111111111111을 입력했다면?
image
이렇게 에러메시지가 뜹니다..ㅎㅎ 예외처리 해야겠죠?

[before]

app.get('/detail/:id', async(요청, 응답) => {
    // collection에 있는 조건에 맞는 가장 첫번째 document만 가져와주세요.
    let result = await db.collection('shopData').findOne({ _id : new ObjectId(요청.params.id)})
    console.log(result)
    응답.render('detail.ejs', {result: result})
})

[after]

app.get('/detail/:id', async(요청, 응답) => {
    try {
        // collection에 있는 조건에 맞는 가장 첫번째 document만 가져와주세요.
        let result = await db.collection('shopData').findOne({ _id : new ObjectId(요청.params.id)})
        console.log(result)
        응답.render('detail.ejs', {result: result})
    } catch(e) {
        // 에러메시지 출력
        console.log(e)
        // 그냥 응답.send해줘도 되긴한데, status쓰면 user가 어떤 문제인지 잘 파악 가능
           // status(5**): 서버문제임
           // status(4**): user문제임
        응답.status(404).send('url이 이상해서 에러 발생')
    }
})

image