JS - todoList 복습 // 하위요소 / fetch, then, catch 본문
오늘은 투두 리스트를 복습하는 시간을 가졌다.
강의를 들으며 만들었던 페이지는 개인적으로 다소 볼품 없다고 느껴서, 이번에는 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() 처리 중 요청이 제대로 이루어지지 않거나, 나타난 오류를 알려주기 위해 활용했다.
이후 받아온 객체를 활용하여 필요한 정보를 뽑아쓸 수 있었다.
'개발 > JavaScript' 카테고리의 다른 글
JS - Class 문법 / constructor() / import (0) | 2023.01.05 |
---|---|
JS - 허들넘기 / canvas태그 (0) | 2023.01.05 |
JS - sort 메서드 / 로또번호 생성하기 (0) | 2023.01.01 |
JS - reduce 메서드 / 논리연산자 / 단축평가 (0) | 2022.12.31 |
JS - todolist / 날씨 적용하기(API) (0) | 2022.12.30 |