spacing
spacing

Reputation: 780

Using async/await to render information only after db fetching function

So I have a db fetching function, which is fetching data from firebase, this takes some time when you open the page initially, (data is only finished fetching after 700ms), I am trying to implement a way to let me render the initial information from the DB only after I have all the data fetched, using async/await and promises but I'm not able to implement it correctly.

The project is a little library list, getFromDB() gets all the information from firebase onto an array (synching DB with local user), and render() merely renders the information to the page into a neat table format

// Get all books from the FirebaseDB and synchs with myLibrary Array
function getFromDB() {
    return new Promise((resolve, reject) => {
        myLibrary.length = 0; // clears original stored array to get all books again
        firebaseRef.on("value", function (data) {
            data.forEach((book) => {
                //gets each book from firebase creates new book Object to array in the correct order(chronologically)
                property = book.val();
                let addedBook = new Book(
                    property.title,
                    property.author,
                    property.pages,
                    property.read,
                    book.key
                );
                myLibrary.push(addedBook);
            });
        });
        resolve(true); // resolve
    });
}

async function initialRender() {
    await getFromDB();
    render();
}

initialRender();

Still the information is not being rendered, because the render() function runs before any information is finished fetching. If I run render() on the console manually afterwards, everything renders properly, which means the await or the promise is not working as intended.

Upvotes: 0

Views: 436

Answers (1)

namar sood
namar sood

Reputation: 1590

Try moving your resolve(true); call to the end of your firebaseRef.on function. What is happening now is, as firebaseRef.on is an async function and resolve is written after this function not inside of it, resolve(true); will run as soon as getFromDB is run.

// Get all books from the FirebaseDB and synchs with myLibrary Array
function getFromDB() {
    return new Promise((resolve, reject) => {
        myLibrary.length = 0; // clears original stored array to get all books again
        firebaseRef.on("value", function (data) {
            data.forEach((book) => {
                //gets each book from firebase creates new book Object to array in the correct order(chronologically)
                property = book.val();
                let addedBook = new Book(
                    property.title,
                    property.author,
                    property.pages,
                    property.read,
                    book.key
                );
                myLibrary.push(addedBook);
            });
            // resolve moved inside
            resolve(true);
             ^^^^^^^^^^^^
        });
         
    });
}

async function initialRender() {
    await getFromDB();
    render();
}

Upvotes: 4

Related Questions