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

긴장한 곰님의 프로필 이미지
긴장한 곰

작성한 질문수

[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지

좋아요 기능 구현 문제

작성

·

674

0

              {% set like = user and twit and twit['Liker'].map(function(value){ return value.id }).includes(user.id) %}

              {% if user and !like %}

              <button class='like'> 좋아요</button>

              {% else %}

              <button class='unlike'>좋아요 취소</button>

              {% endif %}

안녕하세요! 유튜브는 좋아요 기능 구현의 프론트 부분이 퍼그 코드로 돼있어서 넌적스 코드로 프론트를 구현하기 위해 위와 같이 바꿨는데, 넌적스는 map 함수가 적용이 안되는건지, 아니면 다른 문제가 있는 것인지 계속해서 오류가 발생합니다. 혹시 위 넌적스 코드의 수정법 혹은 넌적스로 좋아요 기능을 구현하는 다른 방법이 있을까요?

답변 3

0

긴장한 곰님의 프로필 이미지
긴장한 곰
질문자

router.get('/hashtag'async (reqresnext=> {
  const query = req.query.hashtag;
  if (!query) {
    return res.redirect('/');
  }
  try {
    const hashtag = await Hashtag.findOne({ where: { title: query } });
    let posts = [];
    if (hashtag) {
      posts = await hashtag.getPosts({ include: [{ model: Userattributes: ['id''nick'] }] });
    }

    return res.render('main', {
      title: `${query} 검색 결과 | NodeBird`,
      twits: posts,
      likes: twits.map((v=> v.Liker.map((v=> v.id)).includes(req.user.id),
    });
  } catch (error) {
    console.error(error);
    return next(error);
  }
});

위와 같이 res.render를 통해 likes 배열을 받아왔고, 이를 이용해

{% if user and not (twit and likes) %}
              <button class='like'>좋아요</button>
              {% elif user and (twit and likes) %}
              <button class='unlike'> 좋아요 취소</button>
             {% endif %}

위와 같이 넌적스 파일을 만들었습니다.

  document.querySelectorAll('.like').forEach(function(tag){
      tag.addEventListener('click',function(){ 
        const isLoggedIn = document.querySelector('#my-id'); 
        const twitId = tag.parentNode.querySelector('.twit-id').value;
        if (isLoggedIn){  
              axios.post(`/post/${twitId}/like`)  
                .then(()=>
                  location.reload(); 
                }) 
                .catch((error)=>
                  console.error(error); 
                }); 
            } 
        });   
    });

      document.querySelectorAll('.unlike').forEach(function(tag){
      tag.addEventListener('click',function(){ 
        const isLoggedIn = document.querySelector('#my-id'); 
        const twitId = tag.parentNode.querySelector('.twit-id').value;
        if (isLoggedIn){  
              axios.delete(`/post/${twitId}/like`)  
                .then(()=>
                  location.reload(); 
                }) 
                .catch((error)=>
                  console.error(error); 
                }); 
          } 
      });   
 }); 

like 버튼과 unlike 버튼의 이벤트 리스너는 위와 깉이 만들었습니다.

그리고 실제로 Like 테이블을 조회해보니 아래와 같이 좋아요 버튼을 누른 사람들이 조회가 됩니다. 

그런데 문제는 좋아요 버튼을 눌러도 좋아요 취소 버튼으로 바뀌지 않습니다. 넌적스 파일에서 if와 elif 문을 잘못 작성한 것인지 이벤트 리스너를 잘못 구성한 것인지 오류가 뜨는 것도 아니다보니 정확한 이유를 찾지 못하겠습니다...

긴장한 곰님의 프로필 이미지
긴장한 곰
질문자

console.log(posts)를 찍어보면 좋아요 버튼을 눌러도 Liker 배열이 계속 비어있다고 나오는데 비어있는 이유를 모르겠습니다

긴장한 곰님의 프로필 이미지
긴장한 곰
질문자

Executing (default): SELECT `Post`.`id`, `Post`.`content`, `Post`.`img`, `Post`.`createdAt`, `Post`.`updatedAt`, `Post`.`UserId`, `User`.`id` AS `User.id`, `User`.`nick` AS `User.nick`, `Liker`.`id` AS `Liker.id`, `Liker`.`nick` AS `Liker.nick`, `Liker->Likes`.`createdAt` AS `Liker.Likes.createdAt`, `Liker->Likes`.`updatedAt` AS `Liker.Likes.updatedAt`, `Liker->Likes`.`UserId` AS `Liker.Likes.UserId`, `Liker->Likes`.`PostId` AS 

`Liker.Likes.PostId` FROM `posts` AS `Post` LEFT OUTER JOIN `users` AS `User` ON `Post`.`UserId` = `User`.`id` AND (`User`.`deletedAt` IS NULL) 

LEFT OUTER JOIN ( `Likes` AS `Liker->Likes` INNER JOIN `users` AS `Liker` ON `Liker`.`id` = `Liker->Likes`.`UserId`) ON `Post`.`id` = `Liker->Likes`.`PostId` AND (`Liker`.`deletedAt` IS NULL) ORDER BY `Post`.`createdAt` DESC;

Likes 테이블은 제대로 생성되는데 as: 'Liker'로 연결해주는데 계속 문제가 생기는 것 같습니다

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

likes는 각각의 게시물별로 좋아요 여부가 담긴 배열입니다. twits for문을 돌릴 때 index도 같이 얻어와서 likes[index] 이런 식으로 접근하셔야 합니다.

긴장한 곰님의 프로필 이미지
긴장한 곰
질문자

해결했습니다! 감사합니다 :)

0

긴장한 곰님의 프로필 이미지
긴장한 곰
질문자

[Line 53, Column 80] parseSignature: expected comma after expression

Template render error: (C:\Users\USER\git\Node.js\nodejsStudy\lecture\nodebird\views\main.html) [Line 53, Column 80]
  parseSignature: expected comma after expression


라고 오류가 발생하고 오류가 발생한 줄의 코드는
{% set like = user and twit and twit['Liker'].map(function(value){ return value.id }).includes(user.id) %}

입니다! 혹시 res.render를 이용한 해결방안에 대해 조금만 더 설명해주실 수 있을까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

res.render에서

twits: posts 아래에

likes: twits.map((v) => v.Likers.map((v) => v.id)).includes(req.user.id))

이런식으로 likes 배열을 넣어주고, 넌적스에서 배열에서 꺼내 쓰면 됩니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

에러 내용 올려주세요. 에러 없으면 저도 해결 못 합니다.

한 가지 방법은 애초에 라우터에서 변수로 만들어서 프론트로 res.render 시 보내는 방법이 있습니다.

긴장한 곰님의 프로필 이미지
긴장한 곰

작성한 질문수

질문하기