DEV Community

Andrés Valdivia Cuzcano
Andrés Valdivia Cuzcano

Posted on

Get data from IndexedDB

There are several ways to get the stored data, each of them will be explained below:

Individual data

To get a single specific object, the get(key) method is used, to which the key of the object to be obtained is passed as a parameter.
The requested data is returned as a result of the request.

💡 This method returns undefined as a result if the stored object has an undefined value or the object doens't exist.

function getStudent(key){
    const request = db.transaction('students')
                   .objectStore('students')
                   .get(key);

    request.onsuccess = ()=> {
        const student = request.result;

        return student;
    }

    request.onerror = (err)=> {
        console.error(`Error to get student information: ${err}`)
    }
}

getStudent('andres@andres.com');
Enter fullscreen mode Exit fullscreen mode

Multiple data

To get all the data from an Object Store there are two possible ways:

getAll()

If you want to get an array with all the data inside an Object Store, the getAll() method is used, for this use case this method has a better performance than using a cursor to go through each of the stored data, since the cursor will create an object for each stored data as the Object Store iterates. Otherwise, getAll() creates all the objects at the same time and returns the array.

function getAllStudents(){
    const request = db.transaction('students')
                   .objectStore('students')
                   .getAll();

    request.onsuccess = ()=> {
        const students = request.result;

        console.log('Got all the students');
        console.table(students)

        return students;
    }

    request.onerror = (err)=> {
        console.error(`Error to get all students: ${err}`)
    }
}

getAllStudents();
Enter fullscreen mode Exit fullscreen mode

cursor

If you want to work with all the data stored in an Object Store independently, it is a good idea to use a cursor, which is a mechanism to iterate over multiple records based on their key.

To use a cursor, it must first be created with the openCursor() method of the objectStore object, once the request is made, the success event is handled where the result of the request is the cursor, within this result we can access the stored data or only its key. When there is no more data or a search result was not obtained, the cursor has the value of undefined. Finally, to move to the next stored data, we use the cursor's continue() method.

I find two use cases for the cursor:

  • When you want to work with each object of an Object Store as it is gotten.
  • When you want to work with the keys of each stored object, since using a cursor is more efficient than the getAll() method for this specific case.

For the example, suppose you have a method that prints the properties of each stored object called printInfo(obj):

function printStudents(){
    const request = db.transaction('students')
                      .objectStore('students')
                      .openCursor();

    request.onsuccess = ()=> {
        const cursor = request.result;

        if(cursor){
            printInfo(cursor.value);
            cursor.continue();
        }else{
            console.log('No more entries')
        }

    }
}

printStudents();
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
clytemnestra profile image
Info Comment hidden by post author - thread only accessible via permalink
c. jones • Edited

getStudent() and getAllStudents() don't work as advertised. They can't possibly work. You're trying to return a result to the caller from the onsuccess callback. Not gonna happen.

Both functions start a database transaction and immediately return undefined to the caller. Sometime later IndexedDB sets request.result and runs the onsuccess callback. onsuccess won't return anything to the code that called the function because (1) it wasn't called by the code that called the function and (2) that code already received undefined as the function result and is long gone by the time onsuccess runs.

Whatever you need to do with the query result has to be done within the onsuccess callback. That's why console.log() works as expected in the getAllStudents() callback, why printInfo() will work in printStudents(), why the db is being updated from within the callback in this code, and why variables in the outer context are being updated directly from callbacks throughout that same example.

Don't crib code without citing the source, don't modify it unless you understand why it works, don't post your code if you haven't test it.

Do rewrite the article. You're a good writer, but don't try to explain what you don't understand. That wasted my time - very rude.

Some comments have been hidden by the post's author - find out more