프로그래밍 일기 — React를 알아보자 5
AJAX와 Try-Catch
지난 글에서 DOM(Document Object Model)이라는 웹 페이지 요소를 조작할 수 있는 API에 대해 알아보았다. 허나 아직 DOM이라는 마법 문서를 충분히 들여다보지 못한 느낌이다. 더 깊게 파면 뭔가 더 나올 것 같았는데, 내 예상대로 정말 더 발견할 보물이 숨어져 있었다.
이번 글에서는 DOM의 좀 더 심화된 활용과 AJAX(Asynchronous JavaScript and XML)라는 새로운 개념의 마법 주문에 대해 알아본다. 과연 JavaScript언어로 만들어진 DOM의 마법 세계 지하는 어떻게 이루어져 있을까?
DOM 심화 학습
DOM 요소 생성 및 추가 메서드
createElement()
: 요소 생성 (tagName
이 인식 안되면HTMLUnknownElement
출력)appendChild()
: 기존 요소내 새 자녀요소 추가removeChid()
: 기존 요소내 기존 자녀요소 제거cloneNode()
: 기존 요소(해당 요소의 자녀 요소들을 모두 포함)를 복제
<!--DOM 요소 조작 예제-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM</title>
</head>
<body>
<h1>My Favorite Foods:</h1>
<ul id="foodList"> <!--사용할 unordered list-->
<li>Pizza</li>
<li>Pommes Frites</li> <!--감자 튀김-->
</ul>
<button id="addButton">Add Tacos</button> <!--이벤트 활용을 위한 버튼 정의-->
<button id="removeButton">Remove Pommes Frites</button> <!--이벤트 활용을 위한 버튼 정의-->
<script>
const addButton = document.querySelector('#addButton'); // id = "addButton"을 가진 요소 선택
const removeButton = document.querySelector('#removeButton'); // id = "removeButton"을 가진 요소 선택
const foodList = document.querySelector('#foodList'); // id = "foodList"을 가진 요소 선택
addButton.addEventListener('click', () => {
const newListItem = document.createElement('li') // 새로운 li 요소 생성
const newListItemText = document.createTextNode('Tacos') // 'Tacos'라는 아이템 추가
newListItem.append(newListItemText) // 'Tacos'라는 아이템을 새로운 li 요소에 추가
foodList.appendChild(newListItem) // id = "foodList" 요소에 새로운 li 요소 추가
})
removeButton.addEventListener('click', () => {
const pommesFrites = document.querySelector('li:nth-child(2)') // 2번째 li 요소 선택
foodList.removeChild(pommesFrites) // 2번째 li 요소 삭제
})
</script>
</body>
</html>
AJAX(Asynchronous JavaScript and XML)활용
- 웹 페이지를 새로고침 하지않고도 동적으로(dynamically) 또한 비동기적으로(asynchronously) 다시 로딩할 수 있게 해주는 기법이다.
- 웹 페이지에서 AJAX를 사용하면,
XMLHttpRequest
객체를 사용해 HTTP 요청을 서버에 전송할 수 있고, 응답을 처리할 수 있다. - AJAX는 기술이나 언어라기보다는, 기존에 존재하는 기술을 새로운 개념으로 이용하는 프로그래밍 기법이다. JavaScript내부적으로 구현된(built-in)
XMLHttpRequest
객체를 활용해서, 웹 사이트 페이지를 새로고침 하지않고도 컨덴츠를 로딩할 수 있게 해주는 AJAX를 웹 페이지에서 구현할 수 있다.
동작 예제 설명
- Http 요청 전
<body>
에 사용할 unordered list (ul
)정의id = “userList”
인 요소 선택- 새로운 Http 요청 생성
- Http 요청 성공시:
- Http 요청에 대한 응답을 JSON형태로 parsing
- parsing된 데이터의 각 멤버에 대해 반복문을 통해 작업 수행(
userData
) - 새로운
<li>
요소 정의 userData
의name
값을 text node로 변환<li>
요소에 text node 추가userList
에li
요소 추가
- Http 요청 실패시:
- 에러 메시지 출력
- Http 요청 처리 후:
- GET HTTP 요청으로 타깃 URL에서 데이터를 가져오기 (JSONPlaceholder API 사용)
- Callback 함수를 통해 처리된 Http 요청을 클라이언트(브라우저에) 송신
<!--DOM 요소 조작 예제-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM</title>
</head>
<body>
<h1>Users</h1>
<ul id = "userList"></ul> <!--사용할 unordered list-->
<script>
const userList = document.querySelector('#userList'); // id = "userList"인 요소 선택
const xhr = new XMLHttpRequest(); // 새로운 Http 요청 생성
xhr.onreadystatechange = function(){ // 1. Http 요청이 상태 변경시 동작할 Callback 함수 정의
if(xhr.readyState === XMLHttpRequest.DONE){ // 2. Http 요청 완료시 수행
if(xhr.status === 200){ // 2-1. Http 요청 성공시 수행
const userData = JSON.parse(xhr.responseText) // 2-2. Http 요청에 대한 응답을 JSON형태로 parsing
userData.forEach(element => { // 2-3. userData의 각 요소에 대해 반복문을 통해 작업 수행
const newUser = document.createElement('li') // 2-4. 새로운 li 요소 정의
const newUserText = document.createTextNode(element.name) // 2-5. userData의 name 값을 text node로 변환
newUser.appendChild(newUserText) // 2-6. li 요소에 text node 추가
userList.appendChild(newUser) // 2-7. userList에 li 요소 추가
});
}else{ // 2-8. Http 요청 실패시(status != 200), 에러 메시지 출력
console.log('There was a problem with the request.');
}
}
}
// 3. GET HTTP 요청으로 타깃 URL에서 데이터를 가져오기 (JSONPlaceholder API 사용)
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users')
// 4. Callback 함수를 통해 처리된 Http 요청을 클라이언트(브라우저에) 송신
xhr.send();
</script>
</body>
</html>
팁 1: JSONPlaceHolder API(https://jsonplaceholder.typicode.com/):
JSON 형태로의 Parsing을 테스트하고, Parsing한 데이터를 가져와 사용할 수 있도록 개발자들에게 JSON 테스트 데이터를 무료로 제공하는 플랫폼이다. 해당 플랫폼에서 URL뒤에 /users
, /posts
, /albums
등을 입력하면 미리 정의된 JSON 형태처럼 보이는 Text 데이터를 제공한다. 개발자는 이를 가져다가 JSON으로 parsing하고 원하는 목적에 활용할 수 있다.
// JSONPlaceHolder API 데이터 예제
// URL뒤 "/users/"를 입력하면 아래와 같은 데이터를 볼 수 있다(https://jsonplaceholder.typicode.com/users)
// (모든 데이터 중 일부만 발췌함)
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna@melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
}
]
예외 처리
- 에러 및 예외 처리는 견고하고 신뢰성있는 코드를 작성하기위한 필수 요소이다.
- try-catch:
try
및catch
는 코드상에서 예외처리를 하기 위해 사용할 수 있는 주요 키워드이다. - 대표적으로 3가지 예외가 존재한다: Syntax(문법) 에러, Runtime(런타임) 에러, 논리 및 연산(Logical) 에러
예외 처리 예제 설명
- 연산 함수 정의:
- 매개변수를 받아
numerator/denominator
나누기 연산 값을 반환 denominator === 0
일시, 에러 메시지 출력
- try-catch문 정의:
- 에러를 발생시킬 연산(
denominator = 0
을 인자로 활용)정의 - 연산 후 에러가 발생되는 조건이면 연산 함수에 정의된 메시지를
error
변수에 저장하여catch
문의 인자로 활용 catch
문으로 넘어가error
변수에 저장된 메시지를 출력
// 예외 처리 예제
// try-catch 기본 문법
try{
// 예외를 발생시킬 코드
} catch (error){ // 에러에 대한 정보를 얻을 수 있는 매개변수
// 예외를 처리할 코드
}
// exceptionhandler.js
function divide(numerator, denominator) { // 연산 함수 정의
if(denominator === 0){ // denominator 매개변수가 0일시에 에러 출력
throw new Error('Error: Division by zero')
}
return numerator/denominator;
}
try{
const result = divide(10, 0) // 에러를 출력하기 위한 연산(10/0)
console.log(result); // 에러 캐이스에 해당하므로, 바로 catch로 넘어간다.
}catch(error){ // 에러 메시지를 담은 error 변수를 인자로 활용
console.log(error.message); // 에러 변수에 기록된 메시지 출력
}
>> node exceptionhandler.js
Error: Division by zero
추가 참고 자료
DOM 요소 생성 및 제거:
- https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
- https://developer.mozilla.org/en-US/docs/Web/API/Element/remove
AJAX:
에러 및 예외 처리:
참조:
(1) https://pixabay.com/photos/pokes-fun-at-sand-shovel-digging-1164459/