'Can't use await in IDBRequest handler transaction finishes before all required async handlers

These are requests that use IndexedDB and awaites:

openRequest.onsuccess = async () => {
    db = openRequest.result
    const {transaction, objectStore, cursorRequest} = getIndexedDbTriplet()

    cursorRequest.onsuccess = e => {
        // @ts-ignore
        const cursor = e.target.result

        // @ts-ignore
        objectStore.count().onsuccess = async e => {
            // @ts-ignore
            if (e.target.result === 0) {
                console.log(`Db doesn't have cart products, trying to fetch from server`)
                if (await isAuthenticated()) {
                    await $.get('/Areas/Cart/GetProducts', products, () => {
                        if (products.length === 0) {
                            console.log(`Server also doesn't have cart products`)
                            return
                        } else {
                            $.each(products, (_, product) => {
                                objectStore.add(product)
                            })
                            console.log(`Added products to db`)
                        }
                    })
                }
            } else if (await isAuthenticated()) {
                await $.get('Areas/Cart/GetProducts', products, () => {
                    if (products.length == 0) {
                        console.log(`Server doesn't have products, uploading to it from db`)
                        if (cursor) {
                            $.post('Areas/Cart/AddProduct', cursor.value)
                        }
                        cursor.continue()
                    }
                    console.log(`Uploaded products to server`)
                })
            }
            transaction.oncomplete = e => console.log(`why`)

            objectStore.getAll().onsuccess = e => {
                // @ts-ignore
                products = e.target.result
                let productsLength = products.length

                let decrementCount = 0
                if (products.length % 4 !== 0) {
                    while (productsLength % 4 !== 0) {
                        productsLength--
                        decrementCount++
                    }
                }

                const div = $('<div>')

                for (let i = 0; i < productsLength; i += 4) {
                    const row = getRow()
                    appendCartProductWidget(products[i], row)
                    appendCartProductWidget(products[i + 1], row)
                    appendCartProductWidget(products[i + 2], row)
                    appendCartProductWidget(products[i + 3], row)
                    div.append(row)
                }

                if (products.length % 4 !== 0) {
                    const row = getRow()
                    for (let i = 0; i < decrementCount; i++) {
                        appendCartProductWidget(products[i], row)
                    }
                    div.append(row)
                }

                $('main').append(div)
            }
        }

    }
    function getRow(): JQuery<HTMLDivElement> {
        return $('<div>', {
            'class': 'row-cols-4 row',
        })
    }
}

I get the following error: Uncaught (in promise) DOMException: Failed to execute 'getAll' on 'IDBObjectStore': The transaction has finished.

Before I made functions asynchronous and awaited them, there were no error with transaction. I need results of ajax requests to continue to execute. How to fix this? How to make transaction doesn't finish.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source