Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- localStorage
- 개발자
- partitioning
- 성장기
- node.js란
- Node.js기본
- SSE
- Partition
- 파티셔닝
- ServerSentEvent
- EventSource
- PostgreSQL
- 실시간알림
- node.js
- 열공하자
- mariadb
- frontend
- Lag
Archives
- Today
- Total
써치킴의 우당탕탕 개발 블로그
[Vue.js][Ch4][영화검색 사이트] 영화 검색 코드 리팩토링 본문
어디서나 사용하는 영화 정보를 요청하는 비동기 함수 생성 (movie.js 안에서만)
_fetchMovies 함수 생성
/* 영화 검색과 관련된 데이터를 취급하는 파일 */
import axios from 'axios'
import _uniqBy from 'lodash/uniqBy' // uniqBy 기능만 사용할 것이기 때문에 lodash/uniqBy 명시
export default {
namespaced: true,
state: () => ({
movies: [],
message: '',
loading: false
}),
getters: {},
mutations: {
/* state를 바꿔줄 수 있는건 mutations 밖에 없기 때문에
state에 정의된 데이터를 통합적으로 갱신할 수 있는 mutation을 만들어준다. */
updateState(state, payload) { // 상태를 갱신할때마다 수정하는 메소드
// Object.keys : 객체 데이터 속성의 이름만 갖고 새로운 배열 데이터 생성 (ex.['movies', 'message', 'loading'])
Object.keys(payload).forEach(key => { // ex. key : movies, message, loading
// state.movies = payload.movies를 동적으로 전표기법을 제거하고 state['movies']라고 지정할 수 있다.
// state['movies'] = payload['movies'] => state[key] = payload[key]
state[key] = payload[key];
})
},
resetMovies(state) {
state.movies = [];
}
},
actions: {
// actions의 메소드에는 context, payload 매개변수를 제공한다.
// context : state, getters.commit 활용
// payload : 인수로 들어온 데이터를 받아줌
async searchMovies({ state, commit }, payload) { // (c, p)로도 사용이 가능하다. (매개변수 이름 변경 가능)
// 최초 요청은 page가 1
const res = await _fetchMovie({
// searchMovies의 payload에 이미 원하는 데이터가 있기 때문에 전개 연산자 사용
...payload,
page : 1
});
// res 검색결과의 data에 실제 검색결과가 존재하므로 res.data 사용
const { Search, totalResults } = res.data; // 검색 결과의 data를 객체구조분해
// context의 commit 활용
commit('updateState', { // updateState 메소드가 실행될 때, 객체가 payload 인수로 전달된다.
movies: _uniqBy(Search, 'imdbID'), // imdbID 기준으로 movies 중복 제거
message: 'Hello world!',
loading: true
});
console.log(totalResults) // ex) frozen을 검색했을 때, 305 => 31번 요청해야함.
console.log(typeof totalResults); // string
const total = parseInt(totalResults, 10); // 10진법의 정수로 형변환
// Math.ceil : 올림 처리
const pageLength = Math.ceil(total / 10); // 305/10을 올림 처리 -> 31번 요청 처리.
// 1번 이상 요청해야한다면, 추가 요청 전송
if(pageLength > 1){
for (let page = 2; page <= pageLength; page++) {
// 영화 목록을 몇개 가져올지(number) 조건문을 이용해 for문 종료
if (page > (payload.number / 10)) break; // for문 종료
// 추가 요청은 page가 2부터 검색
const res = await _fetchMovie({
// searchMovies의 payload에 이미 원하는 데이터가 있기 때문에 전개 연산자 사용
...payload,
page
});
const { Search } = res.data;
/*
* movies에는 이미 영화가 들어가져 있는 상태이기 때문에
* 새로운 요청을 할때마다 새로운 배열을 만들어서 movies에 할당
*/
commit('updateState', {
// ... : 전개 연산자
movies: [
...state.movies,
..._uniqBy(Search, 'imdbID')] // state.movies를 먼저 전개하고, Search 데이터를 전개
});
}
}
}
}
}
function _fetchMovie(payload) {
const {title, type, year, page} = payload;
const OMDB_API_KEY = '7035c60c';
const url = `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=${page}`;
return new Promise((resolve, reject) => {
axios.get(url)
.then(res => {
console.log(res);
resolve(res); // 결과값 반환
})
.catch(err => {
reject(err.message); // 에러 반환
})
})
}
OMDb API는 에러가 발생해도 문제의 내용을 .catch가 아닌 .then에서 발생할 수도 있다.
_fetMovies 함수에서 예외처리해줘야 한다.
mport axios from 'axios'
import _uniqBy from 'lodash/uniqBy' // uniqBy 기능만 사용할 것이기 때문에 lodash/uniqBy 명시
export default {
namespaced: true,
state: () => ({
movies: [],
message: '',
loading: false
}),
getters: {},
mutations: {
/* state를 바꿔줄 수 있는건 mutations 밖에 없기 때문에
state에 정의된 데이터를 통합적으로 갱신할 수 있는 mutation을 만들어준다. */
updateState(state, payload) { // 상태를 갱신할때마다 수정하는 메소드
// Object.keys : 객체 데이터 속성의 이름만 갖고 새로운 배열 데이터 생성 (ex.['movies', 'message', 'loading'])
Object.keys(payload).forEach(key => { // ex. key : movies, message, loading
// state.movies = payload.movies를 동적으로 전표기법을 제거하고 state['movies']라고 지정할 수 있다.
// state['movies'] = payload['movies'] => state[key] = payload[key]
state[key] = payload[key];
})
},
resetMovies(state) {
state.movies = [];
}
},
actions: {
// actions의 메소드에는 context, payload 매개변수를 제공한다.
// context : state, getters.commit 활용
// payload : 인수로 들어온 데이터를 받아줌
async searchMovies({ state, commit }, payload) { // (c, p)로도 사용이 가능하다. (매개변수 이름 변경 가능)
try {
// 최초 요청은 page가 1
const res = await _fetchMovie({
// searchMovies의 payload에 이미 원하는 데이터가 있기 때문에 전개 연산자 사용
...payload,
page : 1
});
// res 검색결과의 data에 실제 검색결과가 존재하므로 res.data 사용
const { Search, totalResults } = res.data; // 검색 결과의 data를 객체구조분해
// context의 commit 활용
commit('updateState', { // updateState 메소드가 실행될 때, 객체가 payload 인수로 전달된다.
movies: _uniqBy(Search, 'imdbID'), // imdbID 기준으로 movies 중복 제거
message: 'Hello world!',
loading: true
});
console.log(totalResults) // ex) frozen을 검색했을 때, 305 => 31번 요청해야함.
console.log(typeof totalResults); // string
const total = parseInt(totalResults, 10); // 10진법의 정수로 형변환
// Math.ceil : 올림 처리
const pageLength = Math.ceil(total / 10); // 305/10을 올림 처리 -> 31번 요청 처리.
// 1번 이상 요청해야한다면, 추가 요청 전송
if(pageLength > 1){
for (let page = 2; page <= pageLength; page++) {
// 영화 목록을 몇개 가져올지(number) 조건문을 이용해 for문 종료
if (page > (payload.number / 10)) break; // for문 종료
// 추가 요청은 page가 2부터 검색
const res = await _fetchMovie({
// searchMovies의 payload에 이미 원하는 데이터가 있기 때문에 전개 연산자 사용
...payload,
page
});
const { Search } = res.data;
/*
* movies에는 이미 영화가 들어가져 있는 상태이기 때문에
* 새로운 요청을 할때마다 새로운 배열을 만들어서 movies에 할당
*/
commit('updateState', {
// ... : 전개 연산자
movies: [
...state.movies,
..._uniqBy(Search, 'imdbID')] // state.movies를 먼저 전개하고, Search 데이터를 전개
});
}
}
} catch (message) {
commit('updateState', {
movies: [], // 에러가 발생하면 영화 정보 초기화
message
})
}
}
}
}
function _fetchMovie(payload) {
const {title, type, year, page} = payload;
const OMDB_API_KEY = '7035c60c';
const url = `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=${page}`;
return new Promise((resolve, reject) => {
axios.get(url)
.then(res => {
if (res.data.Error) { // 응답받은 영화정보 데이터에 에러가 있다면 예외처리
reject(res.data.Error);
}
resolve(res); // 정상동작하면 결과값 반환
})
.catch(err => {
reject(err.message); // 에러 반환
})
})
}
'완벽하게 Vue.js' 카테고리의 다른 글
[Vue.js][Ch4][영화검색 사이트] 영화 아이템 - 텍스트 말줄임 표시와 배경 흐림 처리 (0) | 2022.04.25 |
---|---|
[Vue.js][Ch4][영화검색 사이트] 영화 아이템 - 기본 출력 (0) | 2022.04.25 |
[Vue.js][Ch4][영화검색 사이트] 비동기 - API 비동기 처리 연습 (0) | 2022.04.25 |
[Vue.js][Ch4][영화검색 사이트] 비동기 - 예외처리(then, catch, finally) (0) | 2022.04.25 |
[Vue.js][Ch4][영화검색 사이트] 비동기 - 콜백과 프로미스 객체의 이해 (0) | 2022.04.23 |
Comments