본문 바로가기
Javascript

서버에서 받은 데이터를 forEach() 이용해서 UI 반복 생성하기

by 즐코딩 2023. 2. 23.
반응형

서버에서 받은 데이터를 forEach() 이용해서 UI 반복 생성하기

 

 

이전까지 2~3개의 포스팅을 통해서, Javascript를 이용해서 동적으로 UI를 생성하는 과정을 정리해왔습니다. 기초적인 DOM 조작 및 Data 핸들링에 코딩 근육이 붙었으니, 이번에는 서버에서 받아 온 Data를 이용해서 좀 더 코딩스럽게 구현해보는 과정을 정리해보려고 합니다.

 

서버에서 Data를 내려 받은 후 해당 데이터를 이용해서 아래아 같은  UI를 동적으로 만들어보려고 합니다.

 

NETFLIX 비슷한 OTT 채널이라고 가정해봅시다. 좀비 영화만 주구장창 틀어주는 채널, ZomFLIX.

아주, 흥미진진하죠?

넷플릭스-닮은-ZomFLIX를-만들어봅시다
넷플릭스 닮은 ZomFLIX를 만들어봅시다

 

우선, 서버에서는 이런 정보를 전달 받았다고 가정해봅시다.

const zombies = [
  { id: 0, thumb: "zombie1.jpg", title: "좀비 1화", time: 48 },
  { id: 1, thumb: "zombie2.jpg", title: "좀비 2화", time: 59 },
  { id: 2, thumb: "zombie3.jpg", title: "좀비 3화", time: 55 },
];

 

그리고, 사용된 이미지는 아래 첨부합니다.

zombie1.jpg
0.57MB
zombie2.jpg
0.55MB
zombie3.jpg
0.35MB

 

 

일단 1개를 표시하는 UI를 만들어보자

 

그리고 사용될 템플릿은 다음과 같습니다.

일단은 1화가 표시되도록 해두고, 이것을 반복하면 되는 것이겠죠?(Bootstrap CSS를 사용하고 있습니다!)

<div class="container text-center mt-5">
  <h1 class="mb-5">ZomFLIX</h1>
  <div class="row">

    <div class="col">
      <div class="card" style="width: 18rem">
        <img src="zombie1.jpg" class="card-img-top" alt="..." />
        <div class="card-body">
          <h5 class="card-title">좀비 1화</h5>
          <p class="card-text">러닝타임 : 48 분</p>
        </div>
      </div>

  </div>
</div>

HTML/CSS-코딩으로만-우선-템플릿을-만들어-봆시다
HTML/CSS 코딩으로만 우선 템플릿을 만들어 봆시다

 

일단 1화를 표시하는 내용을 만들어봅니다. 그리고 나서는 반복문을 사용해서 반복해주면 되는 것일테니까, 처음부터 복잡한 결과를 구현하려 하지 말고, 단순하게 분해를 한 후 하나씩 만들어 나가보도록 해봅니다.

 

 

반복 사용되는 HTML 구문은 템플릿으로 만들어 재사용

 

가만 보면 Card 부분의 UI가 반복, 재사용되고 있는 것을 알 수 있습니다. 해당 부분을 변수에 담아 템플릿으로 만들어 둡시다. 그리고 그걸 div.row 엘리먼트에 붙여 봅시다.

 

전체 코드는 아래와 같이 변경했습니다.

<body class="bg-dark-subtle">
  <div class="container text-center mt-5">
    <h1 class="mb-5">ZomFLIX</h1>
    <div class="row">
      <!-- 생성한 카드가 표시될 위치 -->
    </div>
  </div>

  <script>
    const zombies = [  //서버에서 받은 데이터
      { id: 0, thumb: "zombie1.jpg", title: "좀비 1화", time: 48 },
      { id: 1, thumb: "zombie2.jpg", title: "좀비 2화", time: 59 },
      { id: 2, thumb: "zombie3.jpg", title: "좀비 3화", time: 55 },
    ];

    const template = `
      <div class="col">
          <div class="card" style="width: 18rem">
            <img src="zombie1.jpg" class="card-img-top" alt="..." />
            <div class="card-body">
              <h5 class="card-title">좀비 1화</h5>
              <p class="card-text">러닝타임 : 48 분</p>
            </div>
          </div>
        </div>
      `;
  </script>
</body>

 

자, 이제 저 template에 담긴 내용을 div.row에 갖다 붙여봐야겠죠?

 

그런데, 아직 자바스크립트가 무르익지 않은 초보 상태라면, 이 지점에서 여러 번의 삽질이 기다리고 있게 됩니다.

 

 

 

div.row에 붙이기 시도와 실패 - insertAdjacentHTML vs. appendChild

 

 

일단, 저는 insertAdjacentHTML() 메서드를 사용해봅니다. 왠지 기능이 멋져서요.

document.querySelector(".row").insertAdjacentHTML("beforeend", template);

 

결과는 성공! 제대로 잘 표시가 됩니다.

같은-형태를&#44;-Javascript를-이용한-코딩으로-변경했습니다.
같은 형태를, Javascript를 이용한 코딩으로 변경했습니다.

 

한번에 성공하면 왠지 이상한거죠?  내친 김에 appendChild() 메서드로도 바꿔서 실행해봅시다. 아마 안될걸요?

document.querySelector(".row").appendChild(template);

에러-난-것도-억울한데&#44;-영어-해석도-어렵...
에러 난 것도 억울한데, 영어 해석도 어렵...

 

콘솔창에는 에러가 표시됩니다. 물론 좀비도 나타나지 않구요. 저도 처음에는 아주 삽질을 자주 하는 구간이었습니다.

Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

해석 :  에러! Node에서 appendChild' 실행 실패, 파라미터1은 'Node' 타입이 아님. 즐~

 

요점만, 정리하자면, 지금 appendChild로 붙이려는 게 Node 타입이 아니어서 안된다는 소리입니다. 이게 뭔 X.... 싶지만, 쉽게 말하자면 <p> 태그나 <img> 태그 등은 순수한 노드 타입인데, 지금 template을 `백틱`을 이용해서 문자열 구조로 만들었기 때문에, 넌 순수하지 않아! 붙일 수 없어! 라고 에러를 낸다고 생각해주세요.

 

insertAdjacentHTML은 노드가 아니라, HTML 타입으로 갖다 붙이는 거라 상관이 없는 것이구요.(그래서 insertAdjacentHTML을 사용하는 게 저는 더 편하더랍니다.)

 

 

어라? append 였던가? 생각하고 append(template)로도 바꿔서 실행해봅시다. 역시나 이상하게 될걸요?

document.querySelector(".row").append(template);

 

HTML-코드가-마치-TEXT-처럼-붙여지는-결과를-가져옵니다.
HTML 코드가 마치 TEXT 처럼 붙여지는 결과를 가져옵니다.

 

append(template)로 붙여보니, 에러는 발생하지 않았지만, 텍스트처럼 붙여져 버리는군요. 초보 입장에서는 이런 게 정말 미치고 팔딱 뛸 노릇인 지점이 되곤하죠. Javascript 라는 게 원래 그렇습니다.

 

저 차이점을 파고드는 건 지금 목표가 아니니, 아무튼 그렇게 일단은 암기를 해주시고 기억해주는 게 속 편합니다.

 

내친 김에 jQuery로도 코딩을 해봅시다! 왜냐구요? 코드가 보기 편하고 간단하니까요. 비교도 되구요.

 

 

 

div.row에 붙이기 시도 - jQuery

 

jQuery를 사용하기 위해서는 아래 호출 코드를 HTML문서 <head>에 붙여 넣습니다.

<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>

 

그리고 element를 붙여 넣는 JS  코드는 다음과 같이 수정했습니다.

$(".row").append(template);   //유의! 여기의 append는 jQuery의 append 임.

jQuery로도-에러-없이-잘-수행됩니다.-단&#44;append()는-jQuery-명령어입니다.
jQuery로도 에러 없이 잘 수행됩니다. 단,append()는 jQuery 명령어입니다.

 

 

jQuery로도 에러 없이 잘 수행됩니다. 어라? 아까는 append() 안되었는데??

 

같은 스펠링이지만, 서로 소속이 다릅니다. 똑 같이 생긴 녀석이 하나는 Vanilla JS 소속이고 다른 하나는 jQuery 소속입니다. 바로 이러한 점 때문에, Vanilla JS를 먼저 공부하라는 이유이기도 합니다. 초보 때는 늘 헷갈릴 수 밖에 없거든요.

 

 

 

 

자, 제대로 붙였으면 이제 반복을 해봅시다 - forEach() 등장

 

JS 코드 부분을 이렇게 수정해보았습니다. 별거 없습니다. forEach() 반복문 안에 넣은 것 밖에 없습니다.

zombies.forEach(function () {  // forEach() 로 감싸준 것 뿐!!

  const template = `
  <div class="col">
      <div class="card" style="width: 18rem">
        <img src="zombie1.jpg" class="card-img-top" alt="..." />
        <div class="card-body">
          <h5 class="card-title">좀비 1화</h5>
          <p class="card-text">러닝타임 : 48 분</p>
        </div>
      </div>
    </div>
  `;
  $(".row").append(template);
  
});

forEach()-반복문을-통해-3개의-카드가-잘-배치되었습니다.
forEach() 반복문을 통해 3개의 카드가 잘 배치되었습니다.

 

일단 3개의 카드가 forEach()구문을 통해 잘 배치되었으므로, 성공입니다!

 

동일하게 나오는 저 것만, 변수 i 같은 걸 사용해서 배열의 순서에 따라 데이터를 뽑아내면 되겠군요!

뭔가 될 것 같아보이니, 당장 코딩해봅시다!

 

 

 

forEach() 메서드로 데이터를 뽑아내는 방법들

 

백틱기호(`) 사이의 문자열에서 변수를 설정하려면, ${ }를 사용합니다. 잘 아시죠?

 

forEach() 메서드는 배열의 원소를 하나씩 꺼내주니까, 막상 꺼낸 놈이 각각 오브젝트(객체)니까 쩜(.)을 찍어 key를 연결해주는 방법으로 데이터를 뽑아오도록 코딩을 변경했습니다.

const zombies = [
  { id: 0, thumb: "zombie1.jpg", title: "좀비 1화", time: 48 },
  { id: 1, thumb: "zombie2.jpg", title: "좀비 2화", time: 59 },
  { id: 2, thumb: "zombie3.jpg", title: "좀비 3화", time: 55 },
];

zombies.forEach(function (data) {
  const template = `
    <div class="col">
        <div class="card" style="width: 18rem">
          <img src="${data.thumb}" class="card-img-top" alt="..." />
          <div class="card-body">
            <h5 class="card-title">${data.title}</h5>
            <p class="card-text">러닝타임 : ${data.time} 분</p>
          </div>
        </div>
      </div>
    `;
  $(".row").append(template);
});

목표하던-결과물을-성공적으로-만들었습니다.
목표하던 결과물을 성공적으로 만들었습니다.

 

아싸! 성공!! 잘 꺼내서 잘 배치가 됩니다.

 

그런데, 여기서 잠깐 forEach() 메서드만의 독특한 점이 있습니다. 파라미터를 또 하나 사용할 수 있다는 것인데요, 다음과 같이 한번 찍어보시죠.

.zombies.forEach(function (data, i)   // i 자리에는 0, 1, 2, 3.... 배열 원소의 개수 만큼 반복횟수가 남습니다.

 

그래서, 자바스크립트 코드는 다음과 같이 변경할 수도 있습니다.

zombies.forEach(function (data, i) {
  const template = `
    <div class="col">
        <div class="card" style="width: 18rem">
          <img src="${zombies[i].thumb}" class="card-img-top" alt="..." />
          <div class="card-body">
            <h5 class="card-title">${zombies[i].title}</h5>
            <p class="card-text">러닝타임 : ${zombies[i].time} 분</p>
          </div>
        </div>
      </div>
    `;
  $(".row").append(template);
});

 

결과는 역시 원하던 대로 잘 나타납니다.^^

 

그럼 둘 중에 어떤 걸 쓰면 좋냐구요? 그냥 맘에 드시는 걸로 사용하시면 됩니다!

 

 

 

마치며

 

이번 포스팅의 작업 과정을 곰곰히 관찰해보면, 막연하기만 했던 '서버'라는 괴상한 물건으로부터 정보를 받아서 처리가 되는 프로세스에 대한 이해도가 올라갈 것입니다. 뭔가 갈피가 좀 잡히는 것 같기도 하구요.

 

물론, 나중에는 서버단에서의 코딩에도 관심을 더 갖고 공부도 더 해보면서 실력을 쌓아 나가야겠죠.

 

모든 공부가 다 그렇겠지만, 코딩도 워낙 다루는 범위가 많다보니, 몇 달만 지나면 가물가물 해지는 부분도 있기는 합니다만, 그럴 때마다 공부했던 부분을 다시 들춰 살펴보면서 반복하다보면 점점 더 복습하는 시간이 짧아지더라구요. 그러다가 결국 머릿속에 남거나 체화가 되는 것 같습니다.

 

저도 뭐 그 반복의 일환으로 정리겸 블로그 포스팅을 꾸준히 진행하고 있는 이유이기도 합니다.

 

오늘도 즐거운 코딩하세요!

즐거운 코딩생활, 즐코딩.

KINcoding.com

 

 

https://app.kincoding.com 

 

WANTED MBTI

MBTI Girl Match a Lovely Girl Friend 당신과 어울리는 사랑스런 여친을 매칭해드립니다.

app.kincoding.com

 

반응형

댓글