Retrieving Data in Typescript Async Function: Ensuring Data is Returned Once All Code is Executed

I need help with waiting for data to be retrieved before returning it. The code below fetches data from indexedDB and sends it back to a component. I understand that observables or promises can accomplish this, but I am struggling with how to implement them properly. Currently, the return statement executes before the code above completes.

retrieveData() {
    let dbReq = indexedDB.open('myChatDb', 1);
    let db;
    let objectStore;
    let results;
    let transaction;
    let data = new Array();
   dbReq.onsuccess = function (event) {
      db = (event.target as IDBOpenDBRequest).result;
      transaction = db.transaction(["customer-messages"]);
      objectStore = transaction.objectStore('customer-messages');
      results = objectStore.openCursor();
      results.onsuccess = function (event) {
        let cursor = event.target.result;
        if (cursor) {
         data.push(cursor.value);
         cursor.continue();
        } else {
        console.log(data);
        console.log(data.length + " array length line 36");
        }
      }
      return data;
    }

Answer №1

To simplify the handling of event handlers, you can create a function that returns a promise and then use await:

function establishConnection(databaseName) {
    return new Promise((resolve, reject) => {
        let request = indexedDB.open(databaseName, 1);

        request.onsuccess = () => resolve(request.result);
        request.onerror = (event) => reject(new Error('Failed to connect to database'));
    });
}

function fetchObjectStoreData(objectStore) {
    return new Promise((resolve, reject) => {
        let results = objectStore.openCursor();
        let data = [];

        results.onerror => () => reject(new Error('Error fetching data from object store.'));
        results.onsuccess = () => {
            let cursor = event.target.result;
            if (cursor) {
                data.push(cursor.value);
                cursor.continue();
            } else {
                resolve(data);
            }
        };
    });
}        


async getData() {
    const db = await establishConnection('myDatabase');
    const transaction = db.transaction(["transaction-data"]);
    const objectStore = transaction.objectStore('transaction-data');
    
    return await fetchObjectStoreData(objectStore);
}

Answer №2

One way to accomplish this is by utilizing the power of async and await in your code structure. By converting the retrieveData function into an asynchronous function and strategically placing the await keyword where necessary, you can streamline the process of fetching data from a database.

async retrieveData() {
let dbReq = indexedDB.open('myChatDb', 1);
let db;
let objectStore;
let results;
let transaction;
let data = new Array();
await dbReq.onsuccess = function (event) {
  db = (event.target as IDBOpenDBRequest).result;
  transaction = db.transaction(["customer-messages"]);
  objectStore = transaction.objectStore('customer-messages');
  results = objectStore.openCursor();
  results.onsuccess = function (event) {
    let cursor = event.target.result;
    if (cursor) {
     data.push(cursor.value);
     cursor.continue();
    } else {
    console.log(data);
    console.log(data.length + " array length line 36");
    }
  }
  return data;
}

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

Is there a possibility for the code following the await call to be executed in a random order if an async Vuex action is triggered twice?

const actions = { search: debounce( async ({ commit, dispatch, getters, rootGetters }, { page = 1 }) => { commit("setLoading", true); commit("setPage", page); console.log("Starting...") const ...

The traditional function does not have access to a reference to this

For my web development project with Angular 9, I needed to add a typeahead feature using ng bootstrap typeahead. The code provided below worked perfectly: search = (text$: Observable<string>) => text$.pipe( debounceTime(150), disti ...

Having difficulty troubleshooting the /app router application on version 13.4.x

Having trouble debugging a server-side process in my Next.js app that uses the /app router. To reproduce the issue, simply create a new Next.js app with npx create-next-app and select the app router option. I've attempted to attach a debugger to the ...

Utilizing a created OpenAPI client within a React application

Using the command openapi-generator-cli generate -i https://linktomybackendswagger/swagger.json -g typescript-axios -o src/components/api --additional-properties=supportsES6=true, I have successfully generated my API client. However, despite having all th ...

Challenges with Initializing Angular 2 Router

I'm encountering a problem with the Angular 2 Router. My goal is to navigate through my application using a function that utilizes the navigate function from the Router, similar to how it's done in the official example. Here's what I curren ...

I am having trouble retrieving child interface data from API using Angular. Can someone help me figure out what I am doing

Recently started with Angular 7 and could use some guidance. I have a JSON stream that appears as follows: { "Id": 25, "Name": "XYZ Corp", "CompanyAddresses": [ { "Id": 39, "CompanyId": 25, "Address1 ...

Assign a value to a locally scoped variable within an iteration in Angular 2

Within my Angular code, I have the following HTML snippet: <span *ngIf="ControllerType?.AttributeID =='Controller Type'"> <select multiple name="ControllerType.Default" [(ngModel)]="Contro ...

Is it possible for a TypeScript function to be used as a React prop even if it conflicts with the function signature's in

Why does the TypeScript type checker allow a prop with a function parameter that does not strictly match the definition? For example, I have a function called callbackImpl = (str: string): number, which is passed as a React prop parameter defined as callb ...

What is the reason behind TypeScript's lack of reporting an incorrect function return type?

It's surprising to see that TypeScript 4.4.3 does not identify an invalid type for the callback function. It makes sense when the function returns a "non-promise" type, but when it returns a Promise, one would expect TypeScript to recognize that we ne ...

Steps to resolve the "Module not found" error when executing the npm run build command

When running the npm run build command in my application, I encountered a module not found error shown below: npm WARN npm npm does not support Node.js v16.17.0 npm WARN npm You should probably upgrade to a newer version of node as we npm WARN npm can&apos ...

Turn off context menus in the Nebular interface when certain conditions are met

Currently, in my Angular 6 project with Nebular, I am facing the following requirement: I need to showcase a nebular context menu on a table row. The context menu should have dynamic enable/disable functionality based on the status of the table column. ]2 ...

What steps are required to transition an Angular application developed without the Angular CLI into an Angular CLI project?

I've created an Angular app using tools like NPM (without utilizing the Angular CLI). What would be the most efficient way to transition this project into the CLI project structure? I want to have the ability to utilize commands like ng serve. ...

Navigating through Expo with Router v3 tabs, incorporating stack navigation, search functionality, and showcasing prominent titles

I've been working on designing a navigation header similar to the Apple Contacts app, with a large title and search function, but only for the Home Screen. All other tabs should have their own unique settings, like different titles or hidden navigatio ...

Using React to map and filter nested arrays while also removing duplicates

Hello, I recently started working with react and I've encountered a challenge while trying to map an array. const fullMen = LocationMenuStore.menuItems['menu']['headings'].map((headings: any) => { <Typography>{ ...

Dealing with Angular: unresolved promise error occurring with the utilization of pipe and mergemap

Recently, while working on my Angular 6 project, I came across the concepts of pipe and mergemap, which intrigued me. Essentially, I have a scenario where I need to allow the user to choose between two different CSV files stored in the assets folder. The d ...

Tips for concealing information within the column labeled company Name with respect to the field designated as Company Name

I am currently working on an Angular 7 app and I am facing an issue: I cannot hide the data in the column for Company Name. The field "Name" in the report control JSON is labeled as Company Name. The report control is a table that contains various fields ...

Passing a click event to a reusable component in Angular 2 for enhanced functionality

I am currently working on abstracting out a table that is used by several components. While most of my dynamic table population needs have been met, I am facing a challenge with making the rows clickable in one instance of the table. Previously, I simply ...

Transferring data to a different module

I'm currently working on an Angular program where I am taking a user's input of a zip code and sending it to a function that then calls an API to convert it into latitude and longitude coordinates. Here is a snippet of the code: home.component.h ...

Unexpected results can occur when using ngClass and CSS with all unset

Within my Angular 4 project, I am utilizing ngClass on an object that contains a CSS class applied with unset: all within it. Despite knowing that ngClass adds its properties, the expected result was for all values to be unset and the style elements from n ...

Attempting to populate an array with .map that commences with a designated number in Angular using Typescript

Currently, I am attempting to populate an array with a series of numbers, with the requirement that the array begins with a certain value and ends with another. My attempt at this task involved the code snippet below: pageArray = Array(finalPageValue).fil ...