ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MovieApp 만들기) 4.Favorite Button 만들기
    NODE.JS 2021. 4. 27. 22:09

     

     

     

    이번 시간에는 영화 디테일 장면 위에 

    좋아하는 영화에 대한 추가버튼을 만들도록 하고, 옆에는 몇명이 좋아요를 눌렀는지 확인하도록 하자. 

     

    순서는 

    1. favorite model(userFrom, movieId, movieTitle, moviePost, movieRunTime)을 만들고 ,

    2. Favorite button UI 만든 후, 

    3. 몇명이 영화 좋아요를 눌렀는지 정보를 얻고, 

    4. 내가 좋아요 리스트에 넣었는지 정보를 얻은 후에,

    5. 데이터를 화면에 보여주는 순으로 진행한다. 

     

     

    가장먼저 server쪽의 ->models->favorite.js 파일을 만든다. 

    const mongoose = require('mongoose');
    const Schema = mongoose.Schema;
    
    
    const favoriteSchema = mongoose.Schema({
       userFrom: {
           type: Schema.Types.ObjectId,
           ref: 'User' //User하나만 가져오면 모든 정보를 가져올 수 있다. (User.js)
       },
       movieId: {
           type: String
       },
       movieTitle:{
           type: String
       },
       moviePost: {
           type:String
       },
       movieRunTime:{
           type:String
       }
    },{timestamps:true})//생성된 시간 자동처리
    
    
    
    const Favorite = mongoose.model('Favorite', favoriteSchema);
    
    module.exports = { Favorite }

     

     

    그다음 Moviedetail.js에 버튼을 생성한다. 

                    <div style={{display: 'flex', justifyContent: 'flex-end'}}>
                        <Favorite   movieInfo= {Movie} movieId = {movieId} userFrom={localStorage.getItem('userId')}/>
                    </div>
    
    
    

     

     

    그다음 client의 sections->Favorite.js파일을 생성하고 그 파일을 moviedetail.js에 import한다. 

    이 안에는 몽고db에게 요청하는 정보가 담겨있다. 

    import React ,{useEffect, useState} from 'react'
    import Axios from 'axios'
    import {Button} from 'antd';
    
    function Favorite(props) {
    
        const movieId = props.movieId
        const userFrom = props.userFrom
        const movieTitle = props.movieInfo.title
        const moviePost = props.movieInfo.backdrop_path
        const movieRunTime = props.movieInfo.runtime
        
        const [FavoriteNumber, setFavoriteNumber] = useState(0)
        const [Favorited, setFavorited] = useState(false)
    
        let variables = {
            userFrom: userFrom,
            movieId:movieId,
            movieTitle: movieTitle,
            moviePost:  moviePost,
            movieRunTime:movieRunTime
    
        }
     
        useEffect(() => {
            //얼마나 많은 사람들이 favorite버튼을 눌렀는지 mongodb에서 가져와야 한다.(fetch써도 된다)
            //받을 내용
    
            //요청
            Axios.post('/api/favorite/favoriteNumber', variables) 
                .then(response =>{
                    setFavoriteNumber(response.data.FavoriteNumber)
                    if(response.data.success){
                        
    
                    }
                    else{
                        alert('숫자 정보를 가져오는데 실패했습니다.')
                    }
                })
            Axios.post('/api/favorite/favorited', variables) 
                .then(response =>{
                    if(response.data.success){
                        setFavorited(response.data.favorited)
                    }
                    else{
                        alert('정보를 가져오는데 실패했습니다.')
                    }
                })
    
        }, [])
    
    
    
        return (
            <div>
                <Button>{ Favorited ? "Not Favorite" : "Add to Favorite"} {FavoriteNumber}</Button>
            </div>
        )
    }
    
    export default Favorite
     

     

    server->route->favorite.js파일을 생성하고 db랑 소통하여 데이터를 받고 프론트에게 알려주는 코드를 작성한다. 

    const express = require('express');
    const router = express.Router();
    const {Favorite} = require('../models/Favorite');
    
    //index.js 에 써놓으면 앞부분은 지울 수 있다(/api/favorite/favoriteNumber')
    //몇명이 좋아하는지 숫자 가져오기
    router.post('/favoriteNumber',  (req, res) =>{
        //index.js에 bodyparser가 있기 때문에 프론트에서 보낸 movieId를 받을 수 있다. 
    
    
        //mongoDB에서 favorite 숫자를 가져오기
        Favorite.find({"movieId":req.body.movieId})
        //에러가 나면 err표시하고 아니면 info 에 넣는다. 
        .exec(( err, info)=>{ 
            if(err) return res.status(400).send(err)
            //그 다음에 프론트에 다시 숫자정보를 보내주기
            res.status(200).json({success:true, favoriteNumber:info.length})
        })
    
    })
    
    //내가 좋아했던것 정보 가져오기 
    router.post('/favorited',  (req, res) =>{
        //index.js에 bodyparser가 있기 때문에 프론트에서 보낸 movieId를 받을 수 있다. 
    
        //내가 이 영화를 favorite 리스트에 넣었는지 정보를 db에서 가져오기 
        Favorite.find({"movieId":req.body.movieId, "userFrom":req.body.userFrom})
        //에러가 나면 err표시하고 아니면 info 에 넣는다. 
        .exec(( err, info)=>{ 
            if(err) return res.status(400).send(err)
    
            //그 다음에 프론트에 다시 숫자정보를 보내주기
            let result = false; //정보가 있다면 true로 바꿔서 결과 보내주자.
            if(info.length !== 0){
                result = true
            }
            res.status(200).json({success:true, favorited:result})
        })
    
    })
    
    
    
    module.exports = router;
    

     

     

    앞의 /api/favorite부분을 routes를 이용해서 생략한다. index.js에 다음과 같은 부분을 추가한다. 

    //router가 api/favorite으로 시작한다면 route/favorite파일로 가서 뒷부분만 찾아서 붙인다. 
    app.use('/api/favorite',require('./routes/favorite'))
    

     

     

    이번엔 특정 리스트에 영화 목록을 추가하고 빼는 작동을 하는데, 버튼에 쓰여진 문장이 추가되었을때와 안되었을 때 다르게 표시되도록 하자. 

    클라이언트의 Favorite.js파일을 다음과 같이 수정하자. 

    import React ,{useEffect, useState} from 'react'
    import Axios from 'axios'
    import {Button} from 'antd';
    
    function Favorite(props) {
    
        const movieId = props.movieId
        const userFrom = props.userFrom
        const movieTitle = props.movieInfo.title
        const moviePost = props.movieInfo.backdrop_path
        const movieRunTime = props.movieInfo.runtime
        
        const [FavoriteNumber, setFavoriteNumber] = useState(0)
        const [Favorited, setFavorited] = useState(false)
    
        let variables = {
            userFrom: userFrom,
            movieId:movieId,
            movieTitle: movieTitle,
            moviePost:  moviePost,
            movieRunTime:movieRunTime
    
        }
    //..생략
    
        const onClickFavorite = () => {
            if(Favorited){
                Axios.post('/api/favorite/removeFromFavorite', variables)
                .then(response => {
                    if(response.data.success){
                        setFavoriteNumber(FavoriteNumber-1)
                        setFavorited(!Favorited)
                    }else{
                        alert('Favorite list에서 지우는 것을 실패했습니다.')
                    }
                })            
            } else{
                Axios.post('/api/favorite/addToFavorite', variables)
                .then(response => {
                    if(response.data.success){
                        setFavoriteNumber(FavoriteNumber +1)
                        setFavorited(!Favorited)
                    }else{
                        alert('Favorite list에서 추가하는 것을 실패했습니다.')
                    }
                })       
            }
        }
    
        return (
            <div>
                <Button onClick={onClickFavorite}>{ Favorited ? "Not Favorite" : "Add to Favorite"} {FavoriteNumber}</Button>
            </div>
        )
    }
    
    export default Favorite

     

     

    서버쪽에서 db와 소통해서 정보를 가져온다. 

    favorite.js

    const express = require('express');
    const router = express.Router();
    const {Favorite} = require('../models/Favorite');
    
    
    //..생략
    //리스트에서 지우기 
    router.post('/removeFromFavorite',  (req, res) =>{
    
        Favorite.findOneAndDelete({movieId: req.body.movieId, userFrom: req.body.userFrom})//이조건에 맞는 것을 지워달라
            .exec((err,doc)=>{
                if(err) return res.status(400).send(err)
                res.status(200).json({success:true, doc})//보내준 정보 doc는 프론트에 보내준다.
            })
    })
    
    
    //좋아하는 리스트에 추가
    router.post('/addToFavorite',  (req, res) =>{
        
        //객체를 담고 저장(모델 favorite를 이용해서 다큐먼트 인스턴스 생성)(클라이언트에서 가져온 정보 담는다)
        const favorite = new Favorite(req.body)
    
        favorite.save((err, doc) =>{
            if(err) return res.status(400).send(err)
            return res.status(200).json({success:true})
        })
    })
    
    
    module.exports = router;
    

     

     

     

     

    전체적인 Sections/Favorite.js의 모습은 

    import React ,{useEffect, useState} from 'react'
    import Axios from 'axios'
    import {Button} from 'antd';
    
    function Favorite(props) {
    
        const movieId = props.movieId
        const userFrom = props.userFrom
        const movieTitle = props.movieInfo.title
        const moviePost = props.movieInfo.backdrop_path
        const movieRunTime = props.movieInfo.runtime
        
        const [FavoriteNumber, setFavoriteNumber] = useState(0)
        const [Favorited, setFavorited] = useState(false)
    
        let variables = {
            userFrom: userFrom,
            movieId:movieId,
            movieTitle: movieTitle,
            moviePost:  moviePost,
            movieRunTime:movieRunTime
    
        }
     
        useEffect(() => {
            //얼마나 많은 사람들이 favorite버튼을 눌렀는지 mongodb에서 가져와야 한다.(fetch써도 된다)
            //받을 내용
    
            //요청
            Axios.post('/api/favorite/favoriteNumber', variables) 
                .then(response =>{
                    setFavoriteNumber(response.data.favoriteNumber)
                    if(response.data.success){
                        
    
                    }
                    else{
                        alert('숫자 정보를 가져오는데 실패했습니다.')
                    }
                })
            Axios.post('/api/favorite/favorited', variables) 
                .then(response =>{
                    if(response.data.success){
                        setFavorited(response.data.favorited)
                    }
                    else{
                        alert('정보를 가져오는데 실패했습니다.')
                    }
                })
    
        }, [])
    
    
        const onClickFavorite = () => {
            if(Favorited){
                Axios.post('/api/favorite/removeFromFavorite', variables)
                .then(response => {
                    if(response.data.success){
                        setFavoriteNumber(FavoriteNumber-1)
                        setFavorited(!Favorited)
                    }else{
                        alert('Favorite list에서 지우는 것을 실패했습니다.')
                    }
                })            
            } else{
                Axios.post('/api/favorite/addToFavorite', variables)
                .then(response => {
                    if(response.data.success){
                        setFavoriteNumber(FavoriteNumber +1)
                        setFavorited(!Favorited)
                    }else{
                        alert('Favorite list에서 추가하는 것을 실패했습니다.')
                    }
                })       
            }
        }
    
        return (
            <div>
                <Button onClick={onClickFavorite}>{ Favorited ? "Not Favorite" : "Add to Favorite"} {FavoriteNumber}</Button>
            </div>
        )
    }
    
    export default Favorite

     

     

    server쪽의 route 쪽의 favorite.js는 다음과 같은 모습이다. 

    const express = require('express');
    const router = express.Router();
    const {Favorite} = require('../models/Favorite');
    
    //index.js 에 써놓으면 앞부분은 지울 수 있다(/api/favorite/favoriteNumber')
    //몇명이 좋아하는지 숫자 가져오기
    router.post('/favoriteNumber',  (req, res) =>{
        //index.js에 bodyparser가 있기 때문에 프론트에서 보낸 movieId를 받을 수 있다. 
    
    
        //mongoDB에서 favorite 숫자를 가져오기
        Favorite.find({"movieId":req.body.movieId})
        //에러가 나면 err표시하고 아니면 info 에 넣는다. 
        .exec(( err, info)=>{ 
            if(err) return res.status(400).send(err)
            //그 다음에 프론트에 다시 숫자정보를 보내주기
            res.status(200).json({success:true, favoriteNumber:info.length})
        })
    
    })
    
    //내가 좋아했던것 정보 가져오기 
    router.post('/favorited',  (req, res) =>{
        //index.js에 bodyparser가 있기 때문에 프론트에서 보낸 movieId를 받을 수 있다. 
    
        //내가 이 영화를 favorite 리스트에 넣었는지 정보를 db에서 가져오기 
        Favorite.find({"movieId":req.body.movieId, "userFrom":req.body.userFrom})
        //에러가 나면 err표시하고 아니면 info 에 넣는다. 
        .exec(( err, info)=>{ 
            if(err) return res.status(400).send(err)
    
            //그 다음에 프론트에 다시 숫자정보를 보내주기
            let result = false; //정보가 있다면 true로 바꿔서 결과 보내주자.
            if(info.length !== 0){
                result = true
            }
            res.status(200).json({success:true, favorited:result})
        })
    
    })
    
    
    //리스트에서 지우기 
    router.post('/removeFromFavorite',  (req, res) =>{
    
        Favorite.findOneAndDelete({movieId: req.body.movieId, userFrom: req.body.userFrom})//이조건에 맞는 것을 지워달라
            .exec((err,doc)=>{
                if(err) return res.status(400).send(err)
                res.status(200).json({success:true, doc})//보내준 정보 doc는 프론트에 보내준다.
            })
    })
    
    
    //좋아하는 리스트에 추가
    router.post('/addToFavorite',  (req, res) =>{
        
        //객체를 담고 저장(모델 favorite를 이용해서 다큐먼트 인스턴스 생성)(클라이언트에서 가져온 정보 담는다)
        const favorite = new Favorite(req.body)
    
        favorite.save((err, doc) =>{
            if(err) return res.status(400).send(err)
            return res.status(200).json({success:true})
        })
    })
    
    
    module.exports = router;
    

     

     

     

    사진으로 보면, 

     

    좌측의 모습에서 클릭하면 1이 추가되고 not favorite이 되는 것을 확인할 수 있다. 

     

     

     

     

     

     

     

Designed by Tistory.