Loading data and store them in indexeddb database. Periodically I have the database crashes and lost access to it. Give me, please, a solution how use indexeddb asynchronously!
Sample code that I'm use now:
var dataTotal = 0;
var threads = 6;
//openIndexeddbConnection();
function start(total){
dataTotal = total;
for (var i = 0; i < threads; i++) {
loadData(i);
}
}
function loadData(dataNum){
var dataNext = dataNum + threads;
if(dataNext > dataTotal){
//checkEnd();
return;
}
$.ajax({
url: baseUrl,
data: {offset: dataNum},
success: function (data) {
successData(dataNext, data);
},
type: 'GET'
});
}
function successData(dataNext, data){
var dataArray = data.split(';');
saveData(dataArray);
loadData(dataNext);
}
function saveData(dataArray){
putItem();
function putItem(i) {
var count = i || 0;
if(dataArray.length <= i){
return;
}
var transaction = Indexeddb.transaction([dataTableName], "readwrite");
transaction.onsuccess = function (event) {
//continue
putItem(count);
};
var objectStore = transaction.objectStore(dataTableName);
var request = objectStore.add({data: dataArray[count++]});
}
}
You can use promises to load and save data asynchronously to indexedDB. Here are two example functions to load and save data to a simple objectstore in indexedDB.
Asynchronous loading from indexedDB:
function loadFromIndexedDB(storeName, id){
return new Promise(
function(resolve, reject) {
var dbRequest = indexedDB.open(storeName);
dbRequest.onerror = function(event) {
reject(Error("Error text"));
};
dbRequest.onupgradeneeded = function(event) {
// Objectstore does not exist. Nothing to load
event.target.transaction.abort();
reject(Error('Not found'));
};
dbRequest.onsuccess = function(event) {
var database = event.target.result;
var transaction = database.transaction([storeName]);
var objectStore = transaction.objectStore(storeName);
var objectRequest = objectStore.get(id);
objectRequest.onerror = function(event) {
reject(Error('Error text'));
};
objectRequest.onsuccess = function(event) {
if (objectRequest.result) resolve(objectRequest.result);
else reject(Error('object not found'));
};
};
}
);
}
Asynchronous saving to indexedDB:
function saveToIndexedDB(storeName, object){
return new Promise(
function(resolve, reject) {
if (object.id === undefined) reject(Error('object has no id.'));
var dbRequest = indexedDB.open(storeName);
dbRequest.onerror = function(event) {
reject(Error("IndexedDB database error"));
};
dbRequest.onupgradeneeded = function(event) {
var database = event.target.result;
var objectStore = database.createObjectStore(storeName, {keyPath: "id"});
};
dbRequest.onsuccess = function(event) {
var database = event.target.result;
var transaction = database.transaction([storeName], 'readwrite');
var objectStore = transaction.objectStore(storeName);
var objectRequest = objectStore.put(object); // Overwrite if exists
objectRequest.onerror = function(event) {
reject(Error('Error text'));
};
objectRequest.onsuccess = function(event) {
resolve('Data saved OK');
};
};
}
);
}
Example usage code
var data = {'id' : 1, 'name' : 'bla'};
saveToIndexedDB('objectstoreName', data).then(function (response) {
alert('data saved');
}).catch(function (error) {
alert(error.message);
});
// Load some data
var id = 1;
loadFromIndexedDB('objectstoreName', id ).then(function (reponse) {
data = reponse;
alert('data loaded OK');
}).catch(function (error) {
alert(error.message);
});
I've been using idb - a simple library that wraps IndexedDB
with promises. These make asynchronous DB actions much easier to use.
If you're targeting Chrome (or are using a transpiler that supports them) you can use async
and await
to simplify your code:
async function saveData(dataArray) {
const db = await idb.open('YourDB', currentVersion, upgradeFunction);
const tran = await db.transaction('StoreName', 'readwrite');
const store = tran.objectStore('StoreName');
// This will add the items sequentially
for(let item of dataArray) {
await store.add({data:item});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With