Bookshelf

Error: Promised response from onMessage listener went out of scope
 avatar
user_6589705
javascript
7 months ago
5.6 kB
6
Indexable
Never
const books = [];
const RENDER_EVENT = 'render-book';
const SAVED_EVENT = 'saved-book';
const STORAGE_KEY = 'BOOKSHELF-APP';

const isStorageExist = () => typeof Storage !== 'undefined';
const generatId = () => +new Date();
const generateBook = (id, title, author, year, isComplete) => ({ id, title, author, year, isComplete });


document.addEventListener('DOMContentLoaded', function () {
    const frm_submit = document.getElementById('inputBook');
    frm_submit.addEventListener('submit', function (event) {
        event.preventDefault();
        addBooks();
    });

    const searchInput = document.getElementById('searchBookTitle');
    searchInput.addEventListener('input', function () {
        searchBooks();
    });

    if (isStorageExist()) {
        loadDataFromLocalStorage();
    }
});



function searchBooks() {
    const search = document.querySelector('#searchBookTitle').value.toUpperCase();
    const bookContainers = document.querySelectorAll('.book_item');

    bookContainers.forEach(bookItem => {
        const titleElement = bookItem.querySelector('h3');
        const title = titleElement.innerText.toUpperCase();
        const match = title.includes(search);

        if (match) {
            bookItem.style.display = '';
        } else {
            bookItem.style.display = 'none';
        }
    });
}


function addBooks() {
    const {value: bookTitle} = document.getElementById('inputBookTitle');
    const {value: bookAuthor} = document.getElementById('inputBookAuthor');
    const {value: bookYear} = document.getElementById('inputBookYear');
    const bookIsComplete = document.getElementById('inputBookIsComplete').checked;

    const generatedID = generatId();
    const bookObject = generateBook(generatedID, bookTitle, bookAuthor, bookYear, bookIsComplete);
    books.push(bookObject);

    document.dispatchEvent(new Event(RENDER_EVENT));
    saveData();
}


document.addEventListener(RENDER_EVENT, function () {
    const incompleteBookList = document.getElementById('incompleteBookshelfList');
    const completeBookList = document.getElementById('completeBookshelfList');

    incompleteBookList.innerHTML = '';
    completeBookList.innerHTML = '';

    books.forEach(bookItem => {
        const booksListElement = createBook(bookItem);
        (bookItem.isComplete ? completeBookList : incompleteBookList).append(booksListElement);
    });
});



function createBook(bookObject) {

    const createElement = (tag, text, className) => {
        const element = document.createElement(tag);
        element.innerText = text;
        if (className) element.classList.add(className);
        return element;
    };

    const textTitle = createElement("h3", bookObject.title);
    const textAuthor = createElement("p", `Penulis : ${bookObject.author}`);
    const textYear = createElement("p", `Tahun : ${Number(bookObject.year)}`);

    const bookItem = createElement("div", "", "book_item");
    bookItem.append(textTitle, textAuthor, textYear);

    const action = createElement("div", "", "action");

    const btn_delete = createElement("button", "Hapus Buku", "red");
    btn_delete.addEventListener("click", () => removeBook(bookObject.id));

    const btn_label = bookObject.isComplete ? "Belum Selesai Dibaca" : "Selesai Dibaca";
    const buttonAction = bookObject.isComplete ? undoFromCompleted : addBooksCompleted;

    const button = document.createElement("button");
    button.innerText = btn_label;
    button.classList.add("green");
    action.append(button);

    button.addEventListener("click", function () {
        buttonAction(bookObject.id);
    });

    action.append(btn_delete);
    bookItem.append(action);

    return bookItem;
}


function addBooksCompleted(bookId) {
    const bookTarget = findBook(bookId);
    if (bookTarget == null) return;
        bookTarget.isComplete = true;
        document.dispatchEvent(new Event(RENDER_EVENT));
        saveData();
}

function findBook(bookId) {
    for (const bookItem of books) {
        if (bookItem.id === bookId) {
            return bookItem;
        }
    }
    return null;
}


function removeBook(bookId) {
    if (confirm("Hapus buku?")) {
        const bookTarget = findBookIndex(bookId);

        if (bookTarget !== -1) {
            books.splice(bookTarget, 1);
            document.dispatchEvent(new Event(RENDER_EVENT));
            saveData()
            .then(() => {
                alert('Buku terhapus');
            })
            .catch(error => {
                console.error('Error saving data:', error);
            });
        }
    }
}

function undoFromCompleted(bookId) {
    const bookTarget = findBook(bookId);

    if (bookTarget) {
        bookTarget.isComplete = false;
        document.dispatchEvent(new Event(RENDER_EVENT));
        saveData();
    }
}

function findBookIndex(bookId) {
    return books.findIndex(book => book.id === bookId);
}


function saveData() {
    if (isStorageExist()) {
        return new Promise((resolve, reject) => {
            try {
                localStorage.setItem(STORAGE_KEY, JSON.stringify(books));
                document.dispatchEvent(new Event(SAVED_EVENT));
                resolve();
            } catch (error) {
                reject(error);
            }
        });
    }
    return Promise.reject(new Error('Storage does not exist'));
}

document.addEventListener(SAVED_EVENT, () => console.log(localStorage.getItem(STORAGE_KEY)));

function loadDataFromLocalStorage() {
    const data = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
    books.push(...data);
    document.dispatchEvent(new Event(RENDER_EVENT));
}

Leave a Comment