Youtube 구현해보기 - 2

박진·2021년 4월 1일
1

오류가 많았다.. 우선 내가 무엇때문에 힘들었는지 다시한번보자.

검색기능을 만드는데 시간을 많이 소비한거같다.

유튜브에서 채널썸네일, 검색기능을 받아오고싶었다.

class Youtube {
  constructor(httpClient) {
    this.youtube = httpClient;
    this.channelList = [];
    this.finalList = [];
    this.channels = {};
  }
  
  async mostPopular() {
    const response = await this.youtube.get("videos", {
      params: {
        part: "snippet",
        chart: "mostPopular",
        maxResults: "25",
        regionCode: "KR",
      },
    });
    const channelList = [];

    response.data.items.map((item) => {
      channelList.push(item.snippet.channelId);
    });
    const finalList = channelList.join();

    const response2 = await this.channel(finalList, response.data.items);
    return response2;
  }
  
async channel(id, videos) {
    const response = await this.youtube.get("channels", {
      params: {
        part: "snippet, statistics",
        id,
      },
    });

    const newId = response.data.items.map((item) => {
      if (item.hasOwnProperty("snippet")) {
        item.channelInfo = item.snippet;
        delete item.snippet;
      }
      return item;
    });

    for (let i = 0; i < 25; i++) {
      const newObj = { ...newId[i], ...videos[i] };
      //   this.finalList.push(newObj);
      newList.push(newObj);
    }
    return newList;
  }
  }

export default Youtube;

우선 mostPopular에서 인기동영상의 api를 받아서 한번에 channelId와 전체 items들을 channel의 인자로 보내어 items들과 새로운 channel data들을 다시 배열로 만들고, channel이 끝나면 값을 리턴하고 싶었다.

그런데 문제는 channelId에서 발생했다. 저런식으로 id값을 모아서 보낼경우 중복된 id가 있을경우 channels API를 얻을때 중복된 값은 제외가 되어 오류가 생기게 된것이다.

오랜고민을 하던끝에 겨우 답을 찾을수있었다.

하나씩 channelId보내기였다

  async mostPopular() {
    const response = await this.youtube.get("videos", {
      params: {
        part: "snippet",
        chart: "mostPopular",
        maxResults: "25",
        regionCode: "KR",
      },
    });

    this.finalList = [];
    
    response.data.items.map((item) => {
      return this.finalList.push(this.channel(item.snippet.channelId, item));
    });
    return Promise.all(this.finalList).then((values) => values);
  }

this.finalList = [];을 초기화해준것은 불러온 리스트들이 계속해서 쌓이기때문에 25개만 계속 보여주기위해서 다시 아무것도 없는 배열값을 주었고, 그래서 mostPopular에서 받은 값을 map을 이용하나 새로운 배열을 만들어 값 하나씩 finalLIst에 push로 넣어주면서 this.channel(item.snippet.channelId, item)호출및 값을 보내주었다. 그리고 Promise.all()메서드를 통해 값을 리턴했다.

여기서 Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환하는 메서드이다.

그리고 다시 channel에서

  async channel(id, videos) {
    const response = await this.youtube.get("channels", {
      params: {
        part: "snippet, statistics",
        id,
      },
    });

    if (response.data.items[0].hasOwnProperty("snippet")) {
      response.data.items[0].channelInfo = response.data.items[0].snippet;
      delete response.data.items[0].snippet;
    }

    return (this.channels = { ...response.data.items[0], ...videos });
  }

같은 방법으로 값을 받아 중복되는 객체의 key인 snippet을 channelInfo로 바꾸어주고 새로운 객체배열을 만들어 리턴해주었다.

이렇게 하니 너무나 잘 작동되는모습을 볼수있었다.

그리고 검색 기능을 추가하였는데,

async search(query) {
    const channelList = [];
    const newList = [];
    const response = await this.youtube.get("search", {
      params: {
        part: "snippet",
        q: query,
        maxResults: "25",
        type: "video",
      },
    });
    this.finalList = [];
    response.data.items.map((item) => {
      return this.finalList.push(this.channel(item.snippet.channelId, item));
    });
    return Promise.all(this.finalList).then((values) => values);
  }

mostPopular와 같이, 이전의 Nav컴포넌트에서 input 의 value값을 query인자로 받아
api를 받고 채널정보를 얻기위해서 다시 한번 mostpopular와같이 수행해주었다.

검색도 잘되는것을 확인할수있었다.

profile
Hello :)

0개의 댓글