drago
drago

Reputation: 1303

How to insert Data into IndexedDB within an AJAX response?

lets say I have a the following code that creates the database OUTSIDE of my Ajax call:

// This works on all devices/browsers, and uses IndexedDBShim as a final fallback 
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

// Open (or create) the database
var open = indexedDB.open("MyDatabase", 1);

// Create the schema
open.onupgradeneeded = function() {
    var db = open.result;
    var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
    var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
};

and then I want to store some data into this database within my Ajax call like so:

 $.ajax({
        url: "https://sometise.com,
        headers: {
            "Authorization": "TOKEN"
        },
        type: "GET",
        success: function (data) {

$(data).each(function (index, el) {

var myArray = {
            ID: el.id,
            Content: data
          }
///ADDING THE ABOVE ARRAY TO THE DATABASE LIKE SO HERE


open.onsuccess = function() {
    // Start a new transaction
    var db = open.result;
    var tx = db.transaction("MyObjectStore", "readwrite");
    var store = tx.objectStore("MyObjectStore");
    var index = store.index("NameIndex");

    // Add some data
    store.put({id: el.id, name: {first: myArray, last: "Doe"}});
    

    // Close the db when the transaction is done
    tx.oncomplete = function() {
        db.close();
    };
}


});


}

  });

but the above code doesn't do anything!

any pointers would be appreciated.

Upvotes: 1

Views: 638

Answers (1)

Mormund
Mormund

Reputation: 368

The open.onsuccess event gets fired only once. This should happen as soon as the DB is ready, which likely happens before the ajax call receives a response from the server. So the event gets fired before you attach the listener, meaning it never gets handled.

You have to store the onsuccess result outside of the ajax callback. Or you can use a promisified version of IDB like https://github.com/jakearchibald/idb and await it inside the ajax callback.

Edit: An example using promises, await and the idb library I mentioned above:

const db = openDB(…);

async function doPost() {
  const response = fetch('https://somesite.com')
  
  const tx = (await db).transaction("MyObjectStore", "readwrite");
  const store = tx.objectStore("MyObjectStore");
  const index = store.index("NameIndex");

  // Add some data
  await store.put(await response);
  await tx.done;
}

Should work like this, but I would recommend reading up about promises in general. Also consider using modern language features like const/let and fetch, they usually make live much easier.

Upvotes: 1

Related Questions