IndexedDB로 포스트 등록하기
IndexedDB로 포스트 등록하기
지난 실습에 이어 이미지를 업로드 하고, 포스트를 등록하는 기능을 구현해봅시다.
브라우저 사이드 데이터베이스 IndexedDB
비동기 개념을 아직 배우지 않은 상태에서 IndexedDB를 완벽하게 이해할 수 없습니다. 따라서 사용방법에 중심을 두고 활용해봅시다.
IndexedDB는 서버에 두는 데이터베이스가 아닌 웹사이트를 이용하고 있는 사용자 브라우저에 종속해 데이터를 저장할 수 있습니다. 쿠키나 로컬 스토리지 등보다 더 많은 데이터를 저장할 수 있습니다. 보다 자세한 내용은 다음 문서를 확인해주세요.
1. Database 생성하기
const request = indexedDB.open(databaseName, version);
Copy
indexDB 객체에서 open메서드에서 데이터베이스 이름과 버전을 지정해줍니다. 버전은 정수만 가능합니다. open 메서드가 실행되고나서 IDBOpenDBRequest 객체가 리턴됩니다.
IDBOpenDBRequest객체 프로퍼티에는 다양한 기능이 있지만, 본 실습에서 사용하는 프로퍼티를 중심으로 살펴보겠습니다.
IDBOpenDBRequest 객체 프로퍼티
- onupgradeneeded: indexedDB의 open메서드를 사용할 때, 현재 버전보다 높은 버전을 사용하면 해당 프로퍼티에 설정한 함수가 실행됩니다.
- onsuccese: indexedDB의 모든 요청이 정상적으로 끝나면 해당 프로퍼티에 설정한 함수가 실행됩니다.
2. Object Store 생성하기
IndexedDB는 데이터베이스 아래 객체 스토어라는 이름으로 또다시 객체를 만들 수 있습니다. 객체 스토어가 모여서 하나의 데이터베이스를 이루는 것과 같이 이해할 수 있습니다.
보통 앞서서 onupgradeneeded 메서드에서 새로운 객체 스토어를 생성합니다.
다음 코드를 살펴보세요.
request.onupgradeneeded = function () {
// 요청의 결과를 리턴합니다.
const db = request.result;
//posts라는 객체 스토어를 생성합니다.
db.createObjectStore("posts", { autoIncrement: true });
};
Copy
객체 스토어는 쉽게 말해 자바스크립트 일반 객체를 생각하면 됩니다. autoIncrement라는 옵션은 자동으로 객체 프로퍼티에 Key를 정수로 1부터 부여합니다.
3. 객체 스토어에 데이터 저장하기
다음 코드를 먼저 살펴봅시다.
const request = indexedDB.open(databaseName, version);
request.onsuccess = function () {
const db = request.result;
const transaction = db.transaction("posts", "readwrite");
const store = transaction.objectStore("posts");
store.add(content).onsuccess = cb;
};
Copy
indexedDB를 열고 요청된 결과가 성공적이면 결과에 대한 객체의 transaction 메서드를 이용해 posts 객체 스토어를 readwrite읽고 쓰겠다는 권한을 설정해줍니다. 그리고 objectStore를 통해 객체 스토어를 가져오고 해당 스토어에 add메서드로 데이터를 저장합니다.
4. 객체 스토어에서 데이터 모두 가져오기
const request = indexedDB.open(databaseName, version);
request.onsuccess = function () {
const db = request.result;
const store = db.transaction("posts").objectStore("posts");
store.getAll().onsuccess = function (res) {
console.log(res.target.result);
};
};
Copy
앞에서 데이터를 삽입하는 코드까지 이해했다면 앞선 코드도 빠르게 이해할 수 있습니다. 마찬가지로 objectStore로 객체 스토어를 가져온 뒤에 getAll 메서드를 이용해 데이터를 모두 가져올 수 있습니다.
indexedDB를 이용해 포스트를 최종적으로 등록해봅시다!
지시사항
이번 실습에서 필요한 스타일은 index.css에 이미 추가되어 있습니다. 주석을 참고하여 꼭 확인해보세요.
- shareBtn 요소에 클릭 이벤트를 추가합니다.
- IndexedDB 데이터베이스를 생성 합니다.
- posts라는 ObjectStore를 생성합니다.
- indexedDB에 transaction을 통해 사용자가 입력한 데이터를 넣어보세요.
- 개발자 도구 > Appliction에서 데이터가 잘 들어가는지 확인해보세요.
실행화면!

아래는 공부용으로 적은 코드.
import close from './assets/close_icon.svg';
import media from './assets/media_icon.svg';
import arrow from './assets/arrow_back_icon.svg';
const modal = `
<div class="modal__close">
<img
width="22px"
height="22px"
src=${close}
alt="close_icon_logo"
/>
</div>
<div class="modal__card">
<div class="modal__header">
<div class="modal__back">
<img width="32px" height="24px" src=${arrow} alt="arrow_back_icon" />
</div>
<h2>새 게시물 만들기</h2>
<p>공유하기</p>
</div>
<div class="modal__main">
<img src=${media} alt="media_icon" />
<h3>사진과 동영상을 업로드 해보세요.</h3>
<label for="file">
<p>컴퓨터에서 선택</p>
</label>
<input type="file" name="file" id="file" />
</div>
</div>
`;
function createPost(img) {
return `
<div class="modal__post">
<img width="478px" height="478px" src=${img} alt="image" />
<div class="modal__write">
<textarea placeholder="문구 입력..." autofocus></textarea>
</div>
</div>
`;
}
document.querySelector('#add-post').addEventListener('click', createModal);
function createModal() {
const modalEl = document.createElement('div');
modalEl.setAttribute('class', 'modal__layout');
modalEl.innerHTML = modal;
document.querySelector('body').prepend(modalEl);
document.querySelector('.modal__close')
.addEventListener('click', function () {
document.querySelector('body').removeChild(modalEl);
});
const fileEl = document.querySelector('#file');
fileEl.addEventListener('input', function () {
let reader = new FileReader();
reader.readAsDataURL(fileEl.files[0]);
reader.onload = function () {
const imageBase64 = reader.result;
document.querySelector('.modal__card')
.setAttribute('class', 'modal__card write--post');
document.querySelector('.modal__main')
.setAttribute('class', 'modal__main write--post');
const backBtn = document.querySelector('.modal__back > img');
const shareBtn = document.querySelector('.modal__header > p');
backBtn.style.visibility = 'visible';
shareBtn.style.visibility = 'visible';
document.querySelector('.modal__main').innerHTML =
createPost(imageBase64);
backBtn.addEventListener('click', function () {
document.querySelector('body').removeChild(modalEl);
createModal();
});
// 지시사항에 맞춰 shareBtn 요소에 이벤트를 추가하세요.
//데이터 업로드 코드
const dbDataUpLode = () =>{
if(window.indexedDB){
//Database 생성하기
//indexDB 객체에서 open메서드에서 데이터베이스 이름과 버전을 지정해줍니다. 버전은 정수만 가능합니다. open 메서드가 실행되고나서 IDBOpenDBRequest 객체가 리턴됩니다.
//IDBOpenDBRequest객체 프로퍼티에는 다양한 기능이 있지만, 본 실습에서 사용하는 프로퍼티를 중심으로 살펴보겠습니다.
//IDBOpenDBRequest 객체 프로퍼티
//onupgradeneeded: indexedDB의 open메서드를 사용할 때, 현재 버전보다 높은 버전을 사용하면 해당 프로퍼티에 설정한 함수가 실행됩니다.
//onsuccese: indexedDB의 모든 요청이 정상적으로 끝나면 해당 프로퍼티에 설정한 함수가 실행됩니다.
const databaseName = "instagram"
const version = 1;
const request = indexedDB.open(databaseName, version);
console.log(request)
const data = {
content: document.querySelector(".modal__write > textarea").value,
image:imageBase64,
}
//2. Object Store 생성하기
//IndexedDB는 데이터베이스 아래 객체 스토어라는 이름으로 또다시 객체를 만들 수 있습니다. 객체 스토어가 모여서 하나의 데이터베이스를 이루는 것과 같이 이해할 수 있습니다.
//보통 앞서서 onupgradeneeded 메서드에서 새로운 객체 스토어를 생성합니다.
//객체 스토어는 쉽게 말해 자바스크립트 일반 객체를 생각하면 됩니다. autoIncrement라는 옵션은 자동으로 객체 프로퍼티에 Key를 정수로 1부터 부여합니다.
//다음 코드를 살펴보세요.
request.onupgradeneeded = () =>{
request.result
.createObjectStore("posts",{autoIncrement:true})
}
request.onsuccess = () =>{
const store = request.result
.transaction("posts", "readwrite")
.objectStore("posts")
store.add(data)
}
}
}
shareBtn.addEventListener('click', dbDataUpLode)
};
reader.onerror = function (error) {
alert('Error: ', error);
document.querySelector('body').removeChild(modalEl);
};
});
}