본문 바로가기

JS - todoList 복습 // 하위요소 / fetch, then, catch 본문

개발/JavaScript

JS - todoList 복습 // 하위요소 / fetch, then, catch

자전하는명왕성 2023. 1. 4. 19:55

 

오늘은 투두 리스트를 복습하는 시간을 가졌다.

강의를 들으며 만들었던 페이지는 개인적으로 다소 볼품 없다고 느껴서, 이번에는 css에 신경을 썼다. (만족스럽다)

 

오늘 다루는 내용은 저번에 다룰 내용과 크게 다르지 않을 것 같긴 하나, 복습할 당시에는 어렵게 느꼈던 부분이니 다뤄보도록 한다.

  • createElement / appendChild / 토글 추가 및 하위요소 삭제
  • 로컬스토리지 / 하위요소 (children) / contains
  • fetch / then / catch

 

createElement / appendChild / 토글 추가 및 하위요소 삭제

먼저 JS를 통한 하위요소 추가에 대한 부분이다. 

하위 요소 추가는 createElement 메서드로 활용이 가능하다.

// 하위 요소 생성
    const newLi = document.createElement("li");  // li 생성
    const newSpan = document.createElement("span"); // span 생성
    const newBtn = document.createElement("button"); // button 생성
	
// 하위 요소 삽입
    newSpan.textContent = todoContents; // span 내 todoContents 삽입
    newLi.classList.add("li_class"); // li 내 class 삽입
    newLi.appendChild(newBtn); // li 내 button 삽입
    newLi.appendChild(newSpan); // li 내 span 삽입
    ulList.appendChild(newLi); // ulList 내 li 삽입

 

이해하기 좋은 순서는 이렇다.

상위 요소 -> 하위 요소 순으로 요소를 만들고,

하위 요소 -> 상위 요소 순으로 요소를 삽입한다.

따라서, 이 순서로 코드가 이루어질 경우, 아래와 같이 HTML 에 그려지게 된다.

<ul id="ul_list">
    <li>
    	<button></button>
        <span class="li_class"> todoContents </span>
    </li>
</ul>

 

토글 삽입 및 요소 삭제

// 클릭 시 'complete' 토글 삽입
	newBtn.addEventListener("click", () => {
        newLi.classList.toggle("complete");
    });
    
// 더블 클릭 시 해당 li 요소 삭제
    newLi.addEventListener("dblclick", () => {
        newLi.remove();
    });

 

로컬스토리지 / 하위요소 (children) / contains

로컬 스토리지 내에 저장하는 방법이다.

const saveItemsFn = function () {
    const saveItems = []; // 객체들을 저장할 배열
    for (let i = 0; i < ulList.children.length; i++) {
        const todoObj = { // contents, complete 저장할 객체
        	// 리스트 li가 가진 contents // 이때 children은 ulList의 하위요소
            contents: ulList.children[i].querySelector("span").textContent,
            // 리스트 li가 가진 complete // 이때 contains은 해당요소를 가졌는지 true || false로 반환
            complete: ulList.children[i].classList.contains("complete"),
        };
        saveItems.push(todoObj);
    }
	// saveItems 이 없을 시 로컬스토리지 삭제 
    // 있을 시 저장, key : "saved-items-alone", value : JSON.stringify(saveItems)
    saveItems.length == 0
        ? localStorage.removeItem("saved-items-alone")
        : localStorage.setItem("saved-items-alone", JSON.stringify(saveItems));
};

 

해당 요소의 하위 요소를 불러올 수 있는 children 에 대해 익숙해질 필요가 있다.

하위 요소의 id 명을 알고 있지 않아도 가져올 수 있다는 강점을 가지기도 할 뿐더러, 응용할 수 있는 방법이 무진하다.

 

// 'saved-items-alone' = {contents, complete}

// 1 로컬 스토리지에 저장한 내용을 변수에 할당 
const savedTodoList = JSON.parse(localStorage.getItem("saved-items-alone"));

// 3 render 펑션은 savedTodoList[i] 매개변수를, storageData라는 전달인자로 받음
const render = function (storageData) {
    let todoContents = inputTodo.value;
    if (storageData) {
    // 가져온 contents 를 렌더링
        todoContents = storageData.contents;
    }
    // 가져온 complete가 true 일 경우, newLi에 class.complete 삽입
    if (storageData?.complete) {
        newLi.classList.add("complete");
    }
    
// 2 해당 변수를 가져와 렌더링 펑션에 전달 
if (savedTodoList) {
    for (let i = 0; i < savedTodoList.length; i++) {
        render(savedTodoList[i]);
    }
}

 

fetch / then / catch

fetch() 함수는 API를 간편하게 호출할 수 있는 함수이다.

fetch() 함수는 첫 번째 인자로 url, 두 번째로는 옵션 객체를 받고 Promise 타입의 객체를 반환한다.

const openWeatherRes = fetch(
        `url` // 보통 url에서 원하는 동적 요소와 API key를 요구함
    )
     .then((res) => {
     		// API 정보는 JSON 데이터 포멧으로 받기 때문에, 이를 json()을 통해 해소해줘야 함
            // header 가 있으면 JSON.parse 안 먹힘
            return res.json();
        })
        	// 위에서 활용한 then()은 json() 처리 과정에서 pendding 상태가 발생하므로,
            // 온전한 데이터를 받기 위해 다시 then() 함수 사용함
        .then((json) => {
            const weatherData = {
                location: json.name,
                weather: json.weather[0].main,
                temp: json.main.temp,
            };
            weatherDataActive(weatherData);
        })
        	// 에러 발생 시 catch() 함수로 알림
        .catch((err) => {
            // then 을 수행하는 과정 중 에러가 발생하면 catch 발생
            console.log(err);
        });

 

단순히 말하면,

첫번째 then()의 경우, 해당 API 데이터를 받아오기 위한 과정이며

두번째 then()의 경우, 해당 데이터를 활용하기 위해 json() 처리를 해주는 과정이라고 볼 수 있다.

catch() 는 위에서 말했던 것과 같이 then() 처리 중 요청이 제대로 이루어지지 않거나, 나타난 오류를 알려주기 위해 활용했다.

이후 받아온 객체를 활용하여 필요한 정보를 뽑아쓸 수 있었다.

Comments