• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Node.js, Express 게시판 검색기능 만들기 3 : 질문이 있습니다.

검색기능 만들기 3 : 질문이 있습니다.

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 글쓴이
  • #26136

    서영석
    참가자

    server.js 

    const express = require('express');
    const app = express();
    const bodyParser= require('body-parser')
    const MongoClient = require('mongodb').MongoClient;
    const methodOverride = require('method-override')
    app.use(methodOverride('_method'))
    const passport = require('passport');
    const LocalStrategy = require('passport-local').Strategy;
    const session = require('express-session');
    require('dotenv').config()
    app.use(bodyParser.urlencoded({extended: true}))
    app.use(express.urlencoded({extended: true}))
    app.set('view engine', 'ejs');
    app.set('views','./views');
    app.use('/public', express.static('public'));
    app.use(session({secret : '비밀코드', resave : true, saveUninitialized: false}));
    app.use(passport.initialize());
    app.use(passport.session());

        var db;
        MongoClient.connect('mongodb+srv://scott:tiger@cluster0.eeagm.mongodb.net/todoapp?retryWrites=true&w=majority', function(에러, client){
        if (에러) return console.log(에러);
        db = client.db('todoapp');

        //db.collection('post').insertOne( {이름 : 'John', date : 100} , function(에러, 결과){
          //  console.log('저장완료');
        //});

        app.listen(8080, function() {
        console.log('listening on 8080')
        });
    });
        app.get('/pet', function(요청, 응답) {
        응답.send('펫용품 사시오')
    });

    app.get('/beauty', function(요청, 응답) {
        응답.send('뷰티용품 쇼핑할 수 있는 페이지입니다.')
    });

    app.get('/', function(요청, 응답) {
        응답.render('index.ejs')
    });

    app.get('/write', function(요청, 응답) {
        응답.render('write.ejs')
    });

    app.post('/add', function(요청, 응답){ //누가 폼에서 /add post 요청하면
        응답.send('전송완료');
        db.collection('counter').findOne({name : '게시물갯수'}, function(에러, 결과){ //DB.COUNTER 내의 총게시물갯수를 찾음
            console.log(결과.totalPost) //총게시물갯수를 변수에 저장
            var 총게시물갯수 = 결과.totalPost;

            db.collection('post').insertOne({_id : 총게시물갯수 + 1, 제목 : 요청.body.title, 날짜 : 요청.body.date}, function(){ //이제 DB.post에 새게시글 기록함
                console.log('저장완료');
                 //counter라는 콜렉션에 있는 totalPost 라는 항목도 1 증가시켜야함 //updateMany //$set 바꿔주세요 //$inc 증가
                db.collection('counter').updateOne({name : '게시물갯수'},{$inc : {totalPost:1} },function(에러, 결과){ //완료되면 DB.COUNTER 내의 총게시글 갯수 +  1
                    if(에러){return console.log(에러)}
                })
            });

     

        });

     

    });

    app.get('/list',function(요청, 응답){

        db.collection('post').find().toArray(function(에러, 결과){
            console.log(결과);
            응답.render('list.ejs', { posts : 결과 });
        });

    });

    app.get('/search', (요청, 응답) => {
        var 검색조건 = [
            {
              $search: {
                index: 'titleSearch',
                text: {
                  query: 요청.query.value,
                  path: ['제목', '날짜']  // 제목날짜 둘다 찾고 싶으면 ['제목', '날짜']
                }
              }
            },
           { $project : { 제목 : 1, _id : 0, score :{ $meta: "searchScore"} } }
        ]
    console.log(요청.query.value);
    db.collection('post').aggregate(검색조건).toArray((에러, 결과)=>{
        console.log(결과)
        응답.render('search.ejs',{posts : 결과})
        });
    });

    app.delete('/delete', function(요청, 응답){
        console.log(요청.body)
        요청.body._id = parseInt(요청.body._id);
        //요청.body에 담겨온 게시물 번호를 가진 글을 db에서 찾아서 삭제해주세요
        db.collection('post').deleteOne(요청.body, function(에러, 결과){
            console.log('삭제완료');
            응답.status(200).send({ message : '성공했습니다.'});
        })
    })

    //detail로 접속하면 detail.ejs 보여줌
    app.get('/detail/:id',function (요청, 응답){
      db.collection('post').findOne({ _id : parseInt(요청.params.id) }, function(에러, 결과){
          console.log(결과);
          응답.render('detail.ejs', {data : 결과} )
      })  
    });

    app.get('/edit/:id', function(요청, 응답){
        db.collection('post').findOne({ _id : parseInt(요청.params.id)},function(에러, 결과){
            console.log(결과)
            응답.render('edit.ejs',{ post : 결과})    
        })

       
    })

    app.put('/edit', function(요청, 응답){
        //폼에 담긴 제목데이터, 날짜 데이터를 가지고
        //db.collection 에다가 업데이트
        db.collection('post').updateOne({_id : parseInt(요청.body.id)},{$set : {제목:
        요청.body.title,날짜 : 요청.body.date}}, function(에러, 결과){
            console.log('수정완료');
            응답.redirect('/list')
        })
    });

    app.get('/login', function(요청, 응답){
        응답.render('login.ejs')
    });

    app.post('/login', passport.authenticate('local', {
        failureRedirect :'/fall'
    }),   function(요청, 응답) {
        응답.redirect('/')
    });

    app.get('/mypage', 로그인했니, function(요청, 응답){
        요청.user
        console.log(요청.user);
        응답.render('/mypage.ejs', {사용자 : 요청.user})
    })

    //app.get('/signup', function(요청, 응답){
      //  응답.render('/signup.ejs')
    //});

    //function 회원가입했니(요청, 응답, next){
      //  if (요청.user) {
        //    next()
        //}
        //else {
          //  응답.send('회원가입안했는데요?')
       //}
    //}

    function 로그인했니(요청, 응답, next){
        if (요청.user) {
            next()
        }
        else {
            응답.send('로그인안하셨는데요?')
        }
    }

    passport.use(new LocalStrategy({ //인증하는 방법 Strategy
      usernameField: 'id',
      passwordField: 'pw',
      session: true,
      passReqToCallback: false,
    }, function (입력한아이디, 입력한비번, done){
      console.log(입력한아이디, 입력한비번);
      db.collection('login').findOne({ id: 입력한아이디 }, function (에러, 결과){
        if (에러) return done(에러)

        if (!결과) return done(null, false, { message: '존재하지않는 아이디요' })
        if (입력한비번 == 결과.pw){
          return done(null, 결과)
        } else {
          return done(null, false, { message: '비번틀렸어요' })
        }
      })
    }));

    passport.serializeUser(function (user, done) {
        done(null, user.id)
      });
     
      passport.deserializeUser(function (아이디, done) {
        db.collection('login').findOne({id : 아이디}, function(에러,결과){
            done(null, 결과)
        })
       
      });

    list.ejs

    <!doctype html>
    <html>
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

        <link rel="stylesheet" href="/public/main.css">

        <title>todoapp</title>
        <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
      </head>
      <body>
       
        <%- include('nav.html') %>

        <div class="container input-group mb-2">
          <input class="form-control" id="search-input">
          <button class="input-group-append btn btn-danger" id="search">검색</button>
        </div>

        <script>
          $('#search').click(function(){
            var  입력한값 = $('#search-input').val()
            window.location.replace('/search?value=' + 입력한값)
          })
       
        </script>

          <div class="container">
          <ul class="list-group">
            <% for (var i = 0; i < posts.length; i++){ %>
            <li class="list-group-item">
              <p>글번호 : <%=posts[i]._id %></p>
              <h4> 할일 제목 : <%= posts[i].제목 %> </h4>
              <p> 할일 날짜 : <%= posts[i].날짜 %> </p>
              <button class="btn btn-danger delete" data-id="<%= posts[i]._id %>">삭제</button>
            </li>
            <% } %>
          </ul>
        </div>
         
          <script>
            $('.delete').click(function(e){
              var 글번호 = e.target.dataset.id; //내가 누른 버튼에 숨겨진 data-id을 가져와주세요
              var 지금누른거 = $(this);
              $.ajax({
                method : 'DELETE',
                url : '/delete',
                data : { _id : 글번호}
              }).done(function(결과){
                //페이지를 강제로 새로 고침해주세요
                //삭제 버튼을 누른 <li> 요소를 제거해주세요/안보이게
                  console.log('성공했어염')
                  지금누른거.parent('li').fadeOut();

              }).fall(function(xhr, textStatus, errorThrown){
                console.log(xhr, textStatus, errorThrown);
              });
            })

          </script>

        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
      </body>
    </html>

     

    search.ejs

    <!doctype html>
    <html>
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

        <link rel="stylesheet" href="/public/main.css">

        <title>todoapp</title>
      </head>
      <body>
       
        <%- include('nav.html') %>

        <div class="container input-group mb-2">
          <input class="form-control">
          <button class="input-group-append btn btn-danger" id="search">검색</button>
        </div>

        <script>
          $('#search').click(function(){
            var 입력한값 = $('#search-input').val();
            window.location.replace('/search?value=' + 입력한값)
          });
       
          //var 자료 = { 이름 : '값', 이름2 : '값2'}
          ///$.param(자료)

         // $(폼태그).serialize()

        </script>

    <div class="container">
      <ul class="list-group">
        <% for (var i = 0; i < posts.length; i++){ %>
        <li class="list-group-item">
          <p>글번호 : <%=posts[i]._id %></p>
          <h4> 할일 제목 : <%= posts[i].제목 %> </h4>
          <p> 할일 날짜 : <%= posts[i].날짜 %> </p>
          <button class="btn btn-danger delete" data-id="<%= posts[i]._id %>">삭제</button>
        </li>
        <% } %>
      </ul>
    </div>
       
       
         

          <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
         
          <script>
            $('.delete').click(function(e){
              var 글번호 = e.target.dataset.id; //내가 누른 버튼에 숨겨진 data-id을 가져와주세요
              var 지금누른거 = $(this);
              $.ajax({
                method : 'DELETE',
                url : '/delete',
                data : { _id : 글번호}
              }).done(function(결과){
                //페이지를 강제로 새로 고침해주세요
                //삭제 버튼을 누른 <li> 요소를 제거해주세요/안보이게
                  console.log('성공했어염')
                  지금누른거.parent('li').fadeOut();

              }).fall(function(xhr, textStatus, errorThrown){
                console.log(xhr, textStatus, errorThrown);
              });
            })

          </script>

        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
      </body>
    </html>

     

    에러는

    TypeError: C:\Users\sys69\Desktop\todoapp\views\search.ejs:39
       37| <div class="container">

       38|   <ul class="list-group">

    >> 39|     <% for (var i = 0; i < posts.length; i++){ %>

       40|     <li class="list-group-item">

       41|       <p>글번호 : <%=posts[i]._id %></p>

       42|       <h4> 할일 제목 : <%= posts[i].제목 %> </h4>

    Cannot read properties of undefined (reading 'length')
       at eval ("C:\\Users\\sys69\\Desktop\\todoapp\\views\\search.ejs":15:34)
       at search (C:\Users\sys69\Desktop\todoapp\node_modules\ejs\lib\ejs.js:692:17)
       at tryHandleCache (C:\Users\sys69\Desktop\todoapp\node_modules\ejs\lib\ejs.js:272:36)
       at View.exports.renderFile [as engine] (C:\Users\sys69\Desktop\todoapp\node_modules\ejs\lib\ejs.js:489:10)
       at View.render (C:\Users\sys69\Desktop\todoapp\node_modules\express\lib\view.js:135:8)
       at tryRender (C:\Users\sys69\Desktop\todoapp\node_modules\express\lib\application.js:640:10)
       at Function.render (C:\Users\sys69\Desktop\todoapp\node_modules\express\lib\application.js:592:3)
       at ServerResponse.render (C:\Users\sys69\Desktop\todoapp\node_modules\express\lib\response.js:1017:7)
       at C:\Users\sys69\Desktop\todoapp\server.js:99:8
       at C:\Users\sys69\Desktop\todoapp\node_modules\mongodb\lib\utils.js:500:17

     

    이게 검색은 되는데

    오류가 localhost:8080/search 들어 가니 다음과 같은 글이 나오네요 두개의 코드는 똑같아서 에러인가요? 다음강의를 듣기 전에

    해답을 듣고  싶은 게시판에 글을 쓰게 되었습니다.

     

     

     

     

     

     

     

     

    #26141

    codingapple
    키 마스터

    localhost:8080/search?value=어쩌구

    이렇게 들어가야 에러가 안날듯요 /search 경로만 처리해주는 라우트는 안만들어놓으신듯요 

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠