Performing asynchronous tasks within an indexedDB cursor

I am utilizing the indexedDB Promised library to convert the indexedDB API into promises.

It seems that once my fetch operation is completed, my indexed db transaction becomes inactive. Could it be timing out?

The error message I am encountering is:

DOMException: Failed to execute 'delete' on 'IDBCursor': The transaction has finished.

My goal is to delete an item from indexedDB only if the fetch operation is successful. I understand that I could create a new transaction after the fetch to retrieve and remove the item. However, I am curious if there is a more efficient way to achieve this without initiating a new transaction. Am I overlooking something?

Can someone shed light on why this issue is occurring?

DBHelper.DBPromised.then( db => {
  const store = db.transaction('deferredReviews', 'readwrite').objectStore('deferredReviews');
  const submittedRes = {};
  store.openCursor()
    .then(function submitAndDelete(cursor) {
        if (!cursor) return;
        console.log(cursor.value);

        fetch(`${DBHelper.DATABASE_URL}/reviews`, {
          method: 'POST',
          body: JSON.stringify({
            restaurant_id: cursor.value.restaurant_id,
            name: cursor.value.name,
            createdAt: cursor.value.deferredAt,
            rating: cursor.value.rating,
            comments: cursor.value.comments
          })
        })
        .then(response => {
          if (!response.ok) {
            throw Error(response.statusText);
          }
          return response.json();
        })
        // If response is ok then delete from indexedDB.
        .then(review => {
          if (!review) return new Error('Could not submit');
          if (cursor.value.restaurant_name in submittedRes) {
            submittedRes[cursor.value.restaurant_name] = submittedRes[cursor.value.restaurant_name] + 1;
          } else {
            submittedRes[cursor.value.restaurant_name] = 1;
          }
          cursor.delete();
          return cursor.continue().then(submitAndDelete);
        });
    })
    .then(() => {
      if (Object.keys(submittedRes).length === 0 && submittedRes.constructor === Object) return;
        DBHelper.showDeferredSubmitModal(submittedRes);
    });
});

Answer №1

It is not advisable to perform asynchronous operations in indexedDB transactions. Async operations can cause the transaction to time out if there are no pending requests at the end of a JavaScript event loop iteration. This pause introduced by async operations can lead to late binding of subsequent requests, as the transaction may have already timed out by then. It is important to keep transactions short-lived to avoid locking up object stores and causing blocking issues.

To avoid this problem, it is recommended to either complete all async work before or after the transaction, rather than in the middle of it. Alternatively, consider using separate transactions if data integrity is not a concern.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing the background color of .pane and .view elements in an Ionic web application using JavaScript

Looking to modify the background-color of two css selectors, .pane and .view, that are located within the ionic.css file. Despite multiple attempts to do so using JavaScript directly in the index.html file, the changes are not reflected. The code snippet ...

What is the best technique for accessing information from protractor's promises series?

My function successfully retrieves the index of an element with the text "check" and prints it using console.log: function getIndex() { return element.all(by.css(".palette__item.ng-scope>span")).then(function (colorList) { colorList.forEach ...

Is there a method to bypass the need for app.get() for each static file in express?

As I delve into using express.js, I'm faced with the task of serving numerous static files from my server - whether it's a .css, .jpg, .svg, .js, or any other file type. Is there a way to accomplish this without having to manually use app.get() f ...

Guide to adjusting column width in an XLSX worksheet using Angular4

I am trying to convert HTML into an XLSX sheet in Angular using SheetJS. However, I am encountering an issue where the width of each column is limited to 256 only, and I need to increase it. I have attempted to use ws[!cols] of ColInfo, but I am strugglin ...

Transforming a React page into a JSON format and then having the ability to change that JSON back into a React page

Is there a way to easily transform a React page into JSON format so that after saving it, I can render the same page with all its details intact? import React from 'react'; import { useState } from 'react'; const Form = () => { ...

Tips for resolving a 403 error and SSH connection issue on an Azure Web Service website

Recently, my web app created on Azure using Express and Node 18 worked perfectly during development locally. However, when I attempted to host it on an Azure web app, I encountered issues. The site failed to display anything and a 403 error was returned in ...

Understanding the implementation of options within dataTables that have been initialized with an aaData JavaScript array

When initializing my datatable, I used an aaData object and specific options like so: $('#dataTable').dataTable(dataTableObj, { "bPaginate": false, "bLengthChange": false, "bFilter": true, "bSort": false, "bInfo": false, ...

JavaScript's speciality - altering the Jquery fade in and fade out effect on Firefox browsers

Utilizing Jquery, I implemented a feature on a table where moving the mouse over a row changes its color. The Javascript code was specifically designed for IE7 and works flawlessly there. However, when tested in Firefox, the text fades along with the backg ...

How can I mirror just one side of a texture in Three.js / WebGL?

I am attempting to create a kaleidoscopic effect using only one side, but I have a large number of Points and would like the effect to be achieved within the shader. If there is a Threejs trick that can mirror half of the texture or the Points object, that ...

Utilize the functionality of the acuityscheduling API to streamline your

I've experimented with various methods but haven't had any success. Hopefully, you guys can share some insight. I'm utilizing acuityscheduling's API to fetch appointments. According to their documentation, the process should look someth ...

What is the best way to invoke a function in a class from a different class in Angular 6?

Below is the code snippet: import { Component, OnInit, ViewChild } from '@angular/core'; import { AuthService } from '../core/auth.service'; import { MatRadioButton, MatPaginator, MatSort, MatTableDataSource } from '@angular/mater ...

What is the best way to incorporate and manipulate data that is accessed from a Vue Template?

In my Vue project, I am utilizing the CDN method but now require the router functionality. Fortunately, I came across a tutorial that provides a clear explanation on how to set up routing without the need for CLI & Webpack. Check it out here: Following th ...

Guide to posting a webpage with Node.js

As a beginner in node.js, I have recently delved into a project involving user input and the generation of an ICS file. After successfully implementing these features, my next challenge is displaying this data on the /cal page. router.get('/cal' ...

Implementing CORS for a custom route in Sails.js - a complete guide

I am experiencing an issue with my Angular 1.x app that calls APIs in my Sails.js app. Every time I attempt to make API calls from the Angular app, I encounter the following error - XMLHttpRequest cannot load <a href="http://localhost:1337/portal/login ...

What causes the DOM's appendChild() to trigger on('load', ...) while jQuery's append() does not fire?

I have two snippets of code that I am working with: $(document).ready(function() { document.head.appendChild( $('<script />').attr('src', 'source.js').on('load', function() { ... ...

N8N: Deleting JSON Key from Output

Is it possible to remove the json key in my output file? I am unsure of the best approach to achieve this. I would like to return an array of data with all values, not just one value. If you want more information, here is a link to my N8N post: Manipulate ...

What is the best way to store the input value within a variable?

I am developing a new component that includes an input field and a button. The user is required to enter their nickname in the input field. This nickname, captured as the input value, needs to be stored in a variable. This variable is integral to a functio ...

The alignment of the Div element is incorrect following a fixed video in bootstrap

When I place a div after the video, the div appears on top of the video instead of after it. Additionally, when I change min-width: 100% to width: 100%, the content appears before the video when I resize the browser. body{ font-family: 'Mina', ...

Issue with Electron-vue: 'compute:' not functioning as expected

My attempt to create a simple example using the element-ui library was not successful. There are two 'switches' with different active state values: 2 and 1. The values of the switches are supposed to be displayed in <p>{{sw1}}</p> and ...