본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.
리뷰 기능에 대한 CRUD를 구현함
리뷰를 작성하면 작성 데이터를 localStorage에 저장
리뷰마다 고유한 ID를 만들어서 수정, 삭제 시 리뷰들을 구분함
// 리뷰 저장하는 함수
export const saveReview = (id) => {
let date = new Date();
let year = date.getFullYear();
let month = ('0' + (date.getMonth() + 1)).slice(-2)
let days = ('0' + date.getDate()).slice(-2)
let hours = ('0' + date.getHours()).slice(-2)
let minutes = ('0' + date.getMinutes()).slice(-2)
let seconds = ('0' + date.getSeconds()).slice(-2)
let day = year + '-' + month + '-' + days + " " + hours + ":" + minutes + ":" + seconds
const review = {
movieId: id,
reviewer: document.getElementById("reviewer").value,
reviewPass: document.getElementById("review_pass").value,
reviewContent: document.getElementById("review_content").value,
dateTime: day
}
localStorage.setItem(crypto.randomUUID(), JSON.stringify(review));
console.log(localStorage);
}
// 리뷰 리스트 로드하는 함수
export const loadReview = (id) => {
let searchReviews = [];
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
let value = localStorage.getItem(key);
if (JSON.parse(value).movieId === id) {
searchReviews.push([key, JSON.parse(value)]);
}
}
console.log(searchReviews);
searchReviews.sort((a, b) => a[1].dateTime < b[1].dateTime ? -1 : 1);
console.log(searchReviews);
document.getElementById("movie_review_list_box").innerHTML = " ";
searchReviews.forEach((item) => {
let review_list_tmp = `
<hr>
<div class="movie_review_list">
<div class="review_list_left">
<div class="review_img_name_date">
<div class="review_img_box">
<img class="commenter_img" src="./img/commenter_img.png">
</div>
<div class="review_name_date">
<p><b>${item[1].reviewer}</b></p>
<p>${item[1].dateTime}</p>
</div>
</div>
<div class="review_content">
<p>${item[1].reviewContent}</p>
</div>
</div>
<div class="review_list_right">
<div class="update_btn">
<button id="update_btn_${item[0]}" type="button" class="btn btn-outline-warning">수정</button>
</div>
<div class="delete_btn">
<button id="delete_btn_${item[0]}" type="button" class="btn btn-outline-danger">삭제</button>
</div>
</div>
</div>
`
document.getElementById("movie_review_list_box").insertAdjacentHTML("beforeend", review_list_tmp);
document.getElementById(`update_btn_${item[0]}`).addEventListener("click", () => {
updateReview(item[0]);
});
document.getElementById(`delete_btn_${item[0]}`).addEventListener("click", () => {
deleteReview(item[0]);
});
})
}
// 리뷰 수정하는 함수
export const updateReview = (reviewId) => {
const reviewData = JSON.parse(localStorage.getItem(reviewId));
if (prompt("비밀번호를 입력해주세요.", "") === reviewData.reviewPass) {
reviewData.reviewer = prompt("작성자를 입력해주세요.", reviewData.reviewer);
reviewData.reviewContent = prompt("내용을 입력해주세요.", reviewData.reviewContent);
reviewData.reviewPass = prompt("내용을 입력해주세요.", "");
localStorage.removeItem(reviewId);
localStorage.setItem(reviewId, JSON.stringify(reviewData));
alert("변경되었습니다!");
loadReview(reviewData.movieId);
} else {
alert("비밀번호가 틀렸습니다!!");
}
}
// 리뷰 삭제하는 함수
export const deleteReview = (reviewId) => {
const reviewData = JSON.parse(localStorage.getItem(reviewId));
if (prompt("비밀번호를 입력해주세요.", "") === reviewData.reviewPass) {
localStorage.removeItem(reviewId);
alert("삭제 되었습니다");
loadReview(reviewData.movieId);
} else {
alert("비밀번호가 틀렸습니다!!");
}
}
기존의 페이지 단위의 검색을 TMDB의 Search API를 사용하는 방식으로 변경
문자열을 Search API의 쿼리값으로 넘겨주면 그 문자열에 해당하는 영화의 데이터를 넘겨줌
// 제목으로 영화 검색해서 해당 영화 데이터 fetch
export const searchMovieData = async (searchText) => {
try {
const response = await fetch(`https://api.themoviedb.org/3/search/movie?query=${searchText}&include_adult=false&language=ko-KR&page=1`, options);
const data = await response.json();
console.log(data);
return data.results;
} catch (err) {
console.error(err);
}
}
// 제목으로 영화 검색
const searchMovie = async () => {
if ($searchContent.value === "") {
window.alert("검색할 제목을 입력해주세요!!");
} else {
// 슬라이드 삭제
$movieSlide.remove();
// 현재 카드 리스트를 삭제
$movieCards.replaceChildren();
const movieData = await searchMovieData($searchContent.value);
movieData.forEach(item => {
appendCard(item.id, item.title, item.genre_ids, item.poster_path, item.vote_average, $movieCards);
});
}
}
자바스크립트 문법에 익숙해질 수 있다.
apply 함수, bind 함수 및 call 함수가 언제 어떻게 사용되어야 하는지를 설명할 수 있다.
var obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
}
};
obj.method(2, 3); // 1 2 3
obj.method.call({ a: 4 }, 5, 6); // 4 5 6
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
var obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
}
};
obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
var obj = {
a: 1,
method: function (x, y) {
console.log(this.a, x, y);
}
};
obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
자바스크립트의 데이터 종류에 대해 이야기할 수 있고, 각각 메모리에 어떻게 저장되고 사용 되고, 수거 되는지를 이해 할 수 있다.
실행컨텍스트의 정의와, 실행컨텍스트를 이루는 요소 및 그 하위요소를 이해할 수 있다. 이를 통해 함수가 실행될 때 어떠한 과정이 일어나는지를 말할 수 있다.
this가 어떤 환경에서는 무엇으로 채택되는지에 대한 일련의 과정을 설명할 수 있다.
원래는 오후까지 구현할 줄 알았는데, 오전 중으로 모두 구현됨
생각보다 TMDB에서 제공하는 API가 다양했음
팀프로젝트에서 만든 장르별 검색도 TMDB API로 제공됨
하지만 장르로 검색된 데이터는 페이지 단위로 제공됨
이렇게되면 장르 검색을 위한 페이지네이션이 따로 필요해 보임
지금은 Popular 영화 API에만 페이지네이션이 걸려있음
여러 조건을 통한 검색 API : https://developer.themoviedb.org/reference/discover-movie