본문 바로가기

Javascript/응용프로젝트

[뉴스 타임즈] 카테고리 별 데이터 보여주기

이제는 위에 카테고리 메뉴를 이용해봐야겠죠??

괜히 힘들게 만들은게 아니랍니다 .. ㅠㅠ api 별로 무슨 카테고리를 제공하는지 먼저 체크하셔야해요!

먼저 메뉴 탭들을 모두 갖고와야겠죠?

button 으로 만드셔도됩니당. 저는 ul 태그의 li를 사용해주었어요

저희 코드 맨 위에 버튼을 가져오는 코드를 입력하겠습니당.

let news = []; // articles 를 담아줄 변수
const categoryMenu = document.querySelectorAll('#h_menu li');
console.log(categoryMenu)

변수 news 아래에 만들어주겠습니다요.

그리고 콘솔로그로 잘 가져왔는지 꼭 체크!!!!!

이제 이 카테고리메뉴들에게 클릭 이벤트를 줘야겠죠? 클릭을 해야 카테고리 별로 데이터를 보여줄 수 있으니까!?

그래서 저희는 이 많은 li 들을 어떻게 하나씩하나씩 뽑아올까용?

li들을 반복해서 꺼내오면 되겠죠? 그럴 때 좋은게 뭐죠?? for 문이죠? 근데 저희는 for 문 이제 사용 안하죠?

트렌디하게 하기 위해서 forEach() 문 사용해줄거에요 ok??

자 사용해봅시다

let news = []; // articles 를 담아줄 변수

const menu = document.querySelectorAll('#header_menu li')
menu.forEach((menuItem) => {
    menuItem.addEventListener('click', (event)=> getNewsByTopic(event));
})

forEach 문으로 카테고리메뉴에 있는 li 들을 하나씩 갖고오면서 클릭이벤트를 줍니다.

참고로 저는 반응형을 디자인해서 반응형 메뉴 따로 웹 메뉴 따로 있기 때문에 똑같은 작업을 두번 해줘야해요.
그래서  스크립트 다 완료하고 반응형으로 원래 메뉴가 반응형 메뉴로 바뀌어지도록 바꿔놓을려고 합니다! (참고)

근데 클릭했을 때 실행시킬 함수가 필요하죠?? 거기다가 event 를 매개변수로 전달해줄거에요

왜냐?

클릭했을 때 누구를 클릭했는지 알아내야하니까요 ㅎㅎ

sports 카테고리를 클릭했는데, 다른 분야의 뉴스가 나오면 안되는거자나요..

넵 그래서 event.target 이라는 아이를 사용하기 위해서 event 를 사용해줄거에요

event.target 이란 event 를 발생시킨 그 아이를 찾아줍니다. ok? 아주 이지 아주 좋은 아이

이제 getNewsByTopic() 함수를 만들러 가볼까요?

요놈도 api 정보 갖고온 함수 밑에다가 따로 만들어줄게요!

const getLatestNews = async() => {
    // let url = new URL(`https://api.newscatcherapi.com/v2/latest_headlines?countries=KR&topic=business&page_size=4`)
    // let header = new Headers({
    //     'x-api-key' : 'Q28hCAatSyFErugKAwYMhuNF788h_jSDQ5Vfc9I0NBg'
    // })
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
    let data = await response.json()
    news = data.articles // news 변수에 data 안에 있는 articles 넣어주기.

    render();
}

const getNewsByTopic = (event) => {
    console.log('클릭됨', event.target)
}

요 자리에다가 함수를 따로 만들고~

console.log 에 한번 event.target 을 찍으시면 어떤 내용을 가진 li 가 클릭된지 알려줘요

자 그리고 또 써볼꺼는 event.target.textContent 인데, 이것은 무엇이냐~

li 안에 있는 내용을 가져와줍니더!! 꾿~ 한번 가져와보자구용

const getNewsByTopic = (event) => {
    console.log('클릭됨', event.target.textContent)
}

아주 잘 가져와지는 모습? ㅎㅎ

자 이제 저희는 api 에게서 이 카테고리 별의 정보를 가져와야해오

위에 api 데이터 가져오는 방법이랑 똑같아요

url 만 살짝 수정해주시면 된답니다.

먼저 가져온 api 사이트에서 보시면은~~ 

이 카테고리 부분 보이시죠? 어떤 카테고리를 제공해주는지 알려주는겁니당.

이걸 url에 넣으시면 됩니다!!

물론 우리가 만든 클릭 이벤트에 넣어야해요 ok??!!

const getNewsByTopic = async(event) => {
    console.log('클릭됨', event.target.textContent)
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${}&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
}

자 똑같이 url 을 가져오는데 달라진게 뭐죠?!

중간에 category=${}가 들어갔죠?? 와웅~

이 안에 변수는 무엇을 넣어줄거냐면 우리가 클릭한 li 의 내용 입니다!

li 에는 카테고리가 개별로 써져있죠? ㅎㅎ 그걸 여기다가 넣으면 알아서 클릭한 아이의 카테고리 데이터를 가져와주는겁니다.

그래서 이 event.target.textContent 를 변수로 저장해줄거에요

근데 저는 카테고리 내용의 앞글자는 모두 대문자로 처리를 해둔 상태에요

api 사이트에서 알려준 카테고리 이름은 모두 소문자로 되어있죠? ex ) business , entertainment 등등

그래서 얘를 어떻게 할꺼냐면 소문자로 바꾸면서 변수에 저장해줄거에요

이때 사용해줄 함수는

toLowerCase() 라는 함수입니다. 소문자로 바꿔주는 기능을 담당해요

그럼 반대는 뭐죠? 대문자죠? 그건 toUpperCase() 라는 함수여요

자 사용해봅시다.

const getNewsByTopic = async(event) => {
    let topic = event.target.textContent.toLowerCase();
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${topic}&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
}

자 topic 이라는 변수에 저장을 하고~

url 에 비어있던 변수칸에 topic 을 넣어줍시다요

그리고 이제 해야할 게 뭐죠? 이 api 에서 data 를 저장해야겠죠?

위에서 했던 것처럼 똑같이 갖고옵시다 (data 라는 변수에다 저장)

const getNewsByTopic = async(event) => {
    let topic = event.target.textContent.toLowerCase();
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${topic}&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
    let data = await response.json();
    console.log(data)
}

자 제가 전에 그랬죠 서버에서 데이터를 받아오려면 모두 다 기다려야한다고.

그래서 데이터를 받아오는 코드는 꼭 await 를 써줘야해요

이 await 를 사용하는 함수는 꼭 async 함수로 바꿔줘야한다고 !!!! 둘은 짝꿍이라구!!!

할튼 요렇게 하고 data 를 확인합시다 . (클릭 이벤트기때문에 , 어떤 것을 클릭하고 봐야함)

오오 잘 가져와졌다!! ㅎㅎ

위에 했던 거랑 똑같이 가져와졌죠? 여기서 이제 다 똑같아요.. ㅎㅎ

이제 이 articles 를 어떻게 하면됩니까?

뽑아와주면 되겠죵?! ㅎㅎ

data.articles 를 미리 만들어놨던 news 라는 빈 배열 안에 넣어줍시다요 ^^

그래야지 render() 에서 아이템을 하나씩 쏙쏙 빼갖고 ui 에 보여줍니다!

const getNewsByTopic = async(event) => {
    let topic = event.target.textContent.toLowerCase();
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${topic}&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
    let data = await response.json();
    news = data.articles
}

이러고 콘솔로그 확인 ㄱㄱ

아주 잘 가져와진 모습.. ^^ 기특해 기특해

이러고 render() 함수만 호출해주시면 되겠죠?

render() 는 뭐다? ui 에 보여주는 역할을 하는 함수다. 바뀐 모습을 ui 에 보여줘야겠죵.

const getNewsByTopic = async(event) => {
    let topic = event.target.textContent.toLowerCase();
    let response = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${topic}&apiKey=254fba25c1ae4a5d9aa54ad3e2d72dc1`)
    let data = await response.json();
    news = data.articles;

    render();
}

카테고리 별 데이터 보여주기 끝~~